C# 协变赋值不起作用
我试图通过C# 协变赋值不起作用,c#,.net,system.reactive,C#,.net,System.reactive,我试图通过IObservable来概括对象属性更改的通知,但这不是问题的重点。问题的重点是:我将以下赋值报告为无效协方差错误: protected virtual void OnPropertyChanged<T>( string propertyName, T oldValue, T newValue) { IPropertyChangedNotification<Student
IObservable
来概括对象属性更改的通知,但这不是问题的重点。问题的重点是:我将以下赋值报告为无效协方差错误:
protected virtual void OnPropertyChanged<T>(
string propertyName,
T oldValue, T newValue)
{
IPropertyChangedNotification<Student, object> notification =
new PropertyChangedNotification<Student, T>(this,
propertyName, oldValue, newValue);
...
}
受保护的虚拟void OnPropertyChanged(
字符串propertyName,
T旧值,T新值)
{
IPropertyChangedNotification通知=
新物业变更通知(本、,
propertyName、oldValue、newValue);
...
}
报告如下:
无法隐式转换类型
PropertyChangedNotification
至IPropertyChangedNotification
。存在显式转换(是否缺少强制转换?)
以下是完整的代码:
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; }
}
班级学生
{
私有ISubject _subject=
新主题;;
私有字符串_name=null;
公共字符串名
{
得到
{
返回_name;
}
设置
{
var oldValue=_name;
_名称=值;
OnPropertyChanged(“名称”、“旧值”、“名称”);
}
}
受保护的虚拟void OnPropertyChanged(字符串propertyName、T oldValue、T newValue)
{
IPropertyChangedNotification通知=
新物业变更通知(本、,
propertyName、oldValue、newValue);
_主题.OnNext(通知);
}
}
公共类属性更改通知
:i属性更改通知
{
公共财产变更通知(TDeclaringType declaringObject,
字符串propertyName,
TPropertyType旧值,
TPropertyType(新值)
{
DeclaringObject=DeclaringObject;
PropertyName=PropertyName;
OldValue=OldValue;
NewValue=NewValue;
}
公共TDeclaringType DeclaringObject{get;set;}
公共字符串PropertyName{get;set;}
公共TPropertyType OldValue{get;protected set;}
公共TPropertyType NewValue{get;protected set;}
}
公共接口IPropertyChangedNotification
{
TDeclaringType DeclaringObject{get;set;}
字符串PropertyName{get;set;}
TPropertyType旧值{get;}
TPropertyType新值{get;}
}
PS:这不是生产代码。只需练习即可。协方差和逆变仅支持引用类型(要将值类型转换为
对象,需要将其装箱)
因此,您需要将T
约束到class
:
void OnPropertyChanged<T>(string propertyName, T oldValue, T newValue)
where T : class { ... }
然后在主题
中使用它(因为在订阅时无论如何都必须将其转换为具体类型):
ISubject
!=<代码>
。你为什么需要第一个?只需使用var
。正如前面指出的object
=<代码>T。作为一组旁注;尽量避免使用主题。出于兴趣,将INPC事件转化为可观测序列已经有十几种方法解决了;-)这里有一些免费的@LeeCampbell:谢谢你,李。我读了你的文章,很喜欢。我试着用我自己的方式去做。我正在尝试做各种排列和组合,做你书中所有的例子,然后再做一些我自己做的。:-)如果我错了,请纠正我,但参数object!=T
不适用于接口中的协变泛型类型参数tpropertyChangedNotification,其中TPropertyType:class
?碰巧将TPropertyType
限制为引用类型对我没有好处。当然,但是您的代码没有where-TPropertyType:class
子句。糟糕!有没有一种便宜的方法呢?取决于你所说的便宜是什么意思。我建议的两种选择都不贵。为什么需要键入通知类?无论如何,当你订阅时,你必须使用演员阵容。
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; }
}
ISubject<IPropertyChangedNotification<Student>>