c# - 协变分配不起作用

标签 c# .net system.reactive

我正在尝试通过 IObservable<T> 概括对对象属性更改的通知。但这不是问题的重点。问题的重点是:我所做的以下分配报告了无效的协方差错误:

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

    ...
}

此报告:

Cannot implicitly convert type PropertyChangedNotification<UsingSubjectToWatchProperty.Student, T> to IPropertyChangedNotification<UsingSubjectToWatchProperty.Student, object>. An explicit conversion exists (are you missing a cast?)

完整代码如下:

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:这不是生产代码。只是练习东西。

最佳答案

仅引用类型支持协变和逆变(要将值类型转换为 Object 需要装箱)。

所以你需要约束 Tclass :

void OnPropertyChanged<T>(string propertyName, T oldValue, T newValue)
    where T : class { ... }

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

第三种选择是拥有一个没有 TProperty 的接口(interface):

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中使用它(因为在订阅时无论如何都必须将其转换为具体类型):

ISubject<IPropertyChangedNotification<Student>>

关于c# - 协变分配不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38696324/

相关文章:

c# - .NET 通过反射获取私有(private)属性

c# - 如何将阻塞事件转换为 Observable?

c# - 在 Entity Framework 中使用预加载时 ASP NET Core 崩溃

c# - 处理突然的 PayPal 付款取消

c# - MVVM Winforms中MessageBoxService和Messenger的区别

system.reactive - Rx Observable Window 带参数关闭功能

c# - Rx 的真实世界示例

c# - 在不同的屏幕分辨率上处理图片标签的更好方法。

c# - 检查表单是否已显示的正确方法?

c# - 有没有办法使用 XCode 创建 ASP .NET 文件?