none
发现一处MSDN关于“泛型接口“介绍的错误

    问题

  • 原文链接地址如下:

    https://msdn.microsoft.com/zh-cn/library/kwtft8ak(v=vs.140).aspx

    具体错误位置出现在此处:

    Generic interfaces can inherit from non-generic interfaces if the generic interface is contra-variant, which means it only uses its type parameter as a return value. 文中提到:如果泛型接口为逆变的,即仅使用其类型参数作为返回值,则此泛型接口可以从非泛型接口继承。

    一开始阅读时造成了困惑,但联系下文对IEnumerable<T>派生自IEnumerable的描述,很快就发现此处的“contra-variant逆变”是用错了,此处应为“co-variant协变”,对应泛型接口定义中的out参数。


    • 已编辑 zimu38998600 2016年11月1日 6:04 添加标题关键字
    2016年11月1日 6:02

全部回复

  • 首先,IEnumerable<T>:IEnumerable,可以理解为:

    IEnumerable<T> = IEnumerable<object>,应该是逆变(继承角度并非引用角度)。

    这是微软针对内部协变,反变的结构进行分析的,和我们传统理解有差异——一般而言,对于父子类而言:

    协变:子类=>父类。

    逆变:父类=>子类。

    那么当IEnumerable<T>:IEnumerable的时候,可以理解为:

    IEnumerable<out T> <= IEnumerable<out object>

    因此是把IEnumerable<object>内部Current等对象需要强制输出转化成T对象后输出——显然,object => T,这个过程是逆变(讨论的是内部结构的变量object=>T)。

    现在考察泛型接口问题:

    A<T> => A<U>:如果U:T,那么成为“协变”。此时我们用的是A<T>的对象,那么内部,T应该有一种方式可以转化成U,所以内部一定是逆变。

    A<U> => A<T>:如果U:T,成为反变。此时我们用A<U>对象,内部一定有一种方式可以把U=>T,显然是内部的协变。

    所以结论是:如果泛型接口支持“协变”,那么内部一定是支持“反变”的;反之亦然。


    ASP.NET Forum
    StackOverFlow
    FreeRice Donate
    Issues to report



    2016年11月2日 6:08
    版主