为了账号安全,请及时绑定邮箱和手机立即绑定

嵌套的 CoVariance 会变成逆变吗?

嵌套的 CoVariance 会变成逆变吗?

C#
白板的微信 2022-06-18 17:20:51
我理解 CoVariance 和 CotraVariance 的概念,因为当需要将接口标记为只读时,我们会使用T并且对于我们在 T中使用的只写接口,这样可以确保类型安全性超过获取和设置事物的一个对象。但是当我们嵌套这些时,ContraVariance 是如何被视为 CoVariance 的。例如:interface IObservable<out T>{    IDisposable Subscribe(IObserver<T> o);}interface IObserver<in T>{    void OnNext(T t);    void OnError(Exception e);    void OnCompleted();}请举例说明嵌套事物如何改变它们的方差。或者请将我重定向到一个好的阅读材料。提前致谢。
查看完整描述

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。


查看完整回答
反对 回复 2022-06-18
  • 1 回答
  • 0 关注
  • 135 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号