首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >协变分配无效

协变分配无效
EN

Stack Overflow用户
提问于 2016-08-01 10:16:50
回答 1查看 100关注 0票数 3

我试图通过IObservable<T>来概括对对象属性的更改通知,但这不是问题的重点。问题的要点是:下面的任务报告无效的协方差错误:

代码语言:javascript
复制
protected virtual void OnPropertyChanged<T>(
                      string propertyName, 
                      T oldValue, T newValue)
{
    IPropertyChangedNotification<Student, object> notification = 
        new PropertyChangedNotification<Student, T>(this,
        propertyName, oldValue, newValue);

    ...
}

该报告指出:

无法隐式地将类型PropertyChangedNotification<UsingSubjectToWatchProperty.Student, T>转换为IPropertyChangedNotification<UsingSubjectToWatchProperty.Student, object>。存在显式转换(是否缺少强制转换?)

以下是完整的代码:

代码语言:javascript
复制
class Student
{
    private ISubject<IPropertyChangedNotification<Student, object>> _subject = 
       new Subject<IPropertyChangedNotification<Student, object>>();;
    private string _name = null;

    public string Name
    {
        get
        {
            return _name;
        }
        set
        {

            var oldValue = _name;
            _name = value;

            OnPropertyChanged<string>("Name", oldValue, _name);
        }
    }

    protected virtual void OnPropertyChanged<T>(string propertyName, T oldValue, T newValue)
    {
        IPropertyChangedNotification<Student, object> notification = 
            new PropertyChangedNotification<Student, T>(this,
            propertyName, oldValue, newValue);

        _subject.OnNext(notification);
    }
}

public class PropertyChangedNotification<TDeclaringType, TPropertyType>
    : IPropertyChangedNotification<TDeclaringType, TPropertyType>
{
    public PropertyChangedNotification(TDeclaringType declaringObject, 
        string propertyName, 
        TPropertyType oldValue, 
        TPropertyType newValue)
    {
        DeclaringObject = declaringObject;
        PropertyName = propertyName;
        OldValue = oldValue;
        NewValue = newValue;
    }

    public TDeclaringType DeclaringObject { get; set; }
    public string PropertyName { get; set; }

    public TPropertyType OldValue { get; protected set; }
    public TPropertyType NewValue { get; protected set; }
}

public interface IPropertyChangedNotification<TDeclaringType, out TPropertyType>
{
    TDeclaringType DeclaringObject { get; set; }
    string PropertyName { get; set; }

    TPropertyType OldValue { get; }
    TPropertyType NewValue { get; }
}

PS:,这不是生产代码。只是练习一些东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-01 10:24:44

协方差和反向方差只支持引用类型(要将值类型转换为需要装箱的Object )。

因此,您需要将T约束为class

代码语言:javascript
复制
void OnPropertyChanged<T>(string propertyName, T oldValue, T newValue)
    where T : class { ... }

或者,您可以只使用new PropertyChangedNotification<Student, object>()

第三种选择是没有TProperty的接口。

代码语言:javascript
复制
public interface IPropertyChangedNotification<TDeclaringType>
{
    TDeclaringType DeclaringObject { get; set; }
    string PropertyName { get; set; }
}

public interface IPropertyChangedNotification<TDeclaringType, out TPropertyType>
    :  IPropertyChangedNotification<TDeclaringType>
{
    TPropertyType OldValue { get; }
    TPropertyType NewValue { get; }
}

然后在Subject中使用它(因为订阅时必须将它转换为具体类型):

代码语言:javascript
复制
ISubject<IPropertyChangedNotification<Student>>
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38696324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档