1 回答

TA贡献1865条经验 获得超7个赞
让我们为引用类型的“是”关系写⊂(一种修改的小于符号)。例如Elephant ⊂ IMammal,或IMammal ⊂ IAnimal。
先来看IObserver<>:
interface IObserver<in T>
{
void OnNext(T t);
// other members irrelevant
}
“in”表示它是逆变的。逆变的意思:
如果X ⊂ Y,那么IObserver<Y> ⊂ IObserver<X>。
相反,因为当你“应用在两边”时,X和的顺序发生了变化。这类似于将不等式(来自数学)乘以两边的负数。您必须交换不等式的两侧(或将变成 a )。YIObserver<·>⊂⊂⊃
之所以允许它具有IObserver<T>逆变性,T是因为T它只用于方法中的值参数(即OnNext)。
假设我们有一个IObserver<IMammal>. 这可以采取任何方法IMammal。OnNext(IMammal t)这个实例可以作为一个IObserver<Elephant>也?是的,因为如果它可以接受 any IMmammal,那么特别是它可以接受 an Elephant,因此逆变是安全可靠的。因为Elephant"is an" IMammal,所以IObserver<IMammal>"is an" IObserver<Elephant>。
逆变换了关系。
现在,让我们看看另一种类型(现在我们来看看您要问的问题!)。我将其重命名IObservable<>为IVable<>:
interface IVable<out T>
{
IDisposable Subscribe(IObserver<T> o);
}
“out”表示协变。协变意味着:
如果X ⊂ Y,那么IVable<X> ⊂ IVable<Y>。
这就像在数学中将不等式的两边都乘以一个正数。X并且Y不被交换(co-)。
IVable<T>但是,当它有一个方法时,怎么可能是协变的,它Subscribe接受“something with T”呢?那是因为“某物”在T!
让我们看看它是否安然无恙。所以,假设我们有一个实例是IVable<IMammal>. 这意味着它有一个Subscribewhich 可以接受任何IObserver<IMammal>. 但后者是逆变的,所以因为一个IMammal"is an" IAnimal,那么任何IObserver<IAnimal>"is an" IObserver<IMammal>。因此,这向我们表明,我们IVable<IMammal>可以像IVable<IAnimal>协方差所指示的那样发挥作用。所以一切都很好。
结论:将与 in逆变的事物“输入” T,就像“输出” in T。类似地,发送“out”一些与in逆变T的东西,就像“in” in 一样T。
- 1 回答
- 0 关注
- 135 浏览
添加回答
举报