从派生列表到基本的IEnumerable

3

我有以下代码,可以在.NET Framework 4.0及以上版本中编译:

public abstract class MyBase { }
public class MyDerived : MyBase { }

public abstract class MyBaseCollection<T> : IList<T> where T : MyBase
{
    protected readonly IList<T> deriveds = new List<T>();

    public void Test()
    {
        // This line works in .NET versions 4.0 and above, but not in versions below.
        IEnumerable<MyBase> bases = deriveds;
    }

    #region IList members with NotImplementedException
    // ...
    #endregion
}
public class MyDerivedCollection : MyBaseCollection<MyDerived> { }

但是在 .NET Framework 4.0 以下的版本中,我会在以下代码行上收到编译错误:
IEnumerable<MyBase> bases = deriveds;

无法将类型“System.Collections.Generic.IList<T>”隐式转换为“System.Collections.Generic.IEnumerable”。存在显式转换(是否缺少强制转换?)

.NET 4.0 在此方面有什么变化(或引入了什么)?
是否有任何相关文档?

2个回答

5
在 .Net 4.0 中,IEnumerable<T> 接口已经从以下形式更改为: public interface IEnumerable<out T> 请注意,泛型类型参数添加了 out 关键字。这意味着泛型参数是协变的,也就是说可以传递一个更具体的类型。
引用块中的描述为:协变使您能够使用比最初指定的更具体的类型。您可以将 IEnumerable(Visual Basic 中的 IEnumerable(Of Derived))的实例分配给类型为 IEnumerable 的变量。
有关更多信息,请参见 msdn

1

这是关于集合的协变和逆变。请查看链接以获取更多信息。

从.NET Framework 4开始,几个泛型接口具有协变类型参数;例如:IEnumerable、IEnumerator、IQueryable和IGrouping。这些接口的所有类型参数都是协变的,因此类型参数仅用于成员的返回类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接