- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试通过 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>
toIPropertyChangedNotification<UsingSubjectToWatchProperty.Student,
. An explicit conversion exists (are you missing a cast?)
object>
完整代码如下:
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
需要装箱)。
所以你需要约束 T
至 class
:
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/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!