派生列表以IEnumerable为基础

时间:2017-02-14 11:59:27

标签: c# ienumerable .net-2.0

我有以下代码在.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&lt; T&gt;'到'System.Collections.Generic.IEnumerable'。存在显式转换(您是否错过了演员?)

问题是.NET 4.0中有关此问题的更改(或已引入)? 有没有关于此的文件?

2 个答案:

答案 0 :(得分:3)

在.Net 4.0中,IEnumerable<T>界面已更改为:

public interface IEnumerable<T>

public interface IEnumerable<out T>

请注意,out out已添加到泛型类型参数中。这意味着泛型参数是共变量,这意味着您可以传入更多派生类型。

  

协方差使您可以使用比最初更多的派生类型   指定。您可以分配IEnumerable的实例   (IEnumerable(Of Derived)在Visual Basic中)到类型的变量   IEnumerable的

有关详细信息,请参阅msdn

答案 1 :(得分:2)

这是关于收藏品的协方差和逆转。请查看以下link以获取更多信息。

  

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