嵌套的 CoVariance 会变成逆变吗?

我理解 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();

}

请举例说明嵌套事物如何改变它们的方差。或者请将我重定向到一个好的阅读材料。提前致谢。


白板的微信
浏览 136回答 1
1回答

莫回无

让我们为引用类型的“是”关系写⊂(一种修改的小于符号)。例如Elephant ⊂ IMammal,或IMammal ⊂ IAnimal。先来看IObserver<>:interface IObserver<in T>{&nbsp; &nbsp; void OnNext(T t);&nbsp; &nbsp; // 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>{&nbsp; &nbsp; 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。
打开App,查看更多内容
随时随地看视频慕课网APP