2017-02-14 73 views
1

我有下面的代码,在.NET Framework版本编译4.0及以上版本:派生清单基地的IEnumerable

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框架4.0以下我得到下面的行编译错误:

IEnumerable<MyBase> bases = deriveds; 

无法隐式转换类型 'System.Collections.Generic.IList <牛逼>' 到 'System.Collections.Generic.IEnumerable'。存在明确的转换(您是否缺少演员?)

问题是在.NET 4.0中对此进行了更改(或已引入)的内容吗?
有没有关于这方面的任何文件?

回答

3

在.NET 4.0中的IEnumerable<T>界面是改变。这意味着泛型参数是co-variant,这意味着您可以传入更多派生类型。

协方差使您能够使用比原先指定的 更衍生的类型。您可以IEnumerable的 (IEnumerable的(获得)在Visual Basic)的实例分配给 IEnumerable类型的变量

了解更多信息

msdn
2

这是关于收集的协变性和逆变性。检查以下link以获取更多信息。

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

public interface IEnumerable<T>

public interface IEnumerable<out T>

注意,这个词已经被添加到泛型类型参数: