This question already has answers here:
Covariance and IList
                                
                                    (4个答案)
                                
                        
                                5年前关闭。
            
                    
我正在尝试将List转换为IList,但是无法转换。编译器只允许我将其转换为IEnumerable:

//Not allowed, why?
public override IList<ILineEntity> Lines
{
   get { return _PharamaLines ?? (_PharamaLines = new List<PharamaLine>()); }
}

//Allowed
public override IEnumerable<ILineEntity> Lines
{
   get { return _PharamaLines ?? (_PharamaLines = new List<PharamaLine>()); }
}


PharamaLine的类型为ILineEntity


  错误:无法将类型'System.Collections.Generic.List<FW.PharamaLine>'隐式转换为'System.Collections.Generic.IList<Foundation.Interfaces.ILineEntity>'。存在显式转换(您是否缺少演员表?)

最佳答案

原因是:

IList<T>是不变的,而IEnumerable<out T>是协变的(out关键字)。

如果定义List<PharamaLine>,则基本上可以说明只能将PharmaLine对象添加到列表中,但是可以将不同的ILineEntity对象添加到IList<ILineEntity>中,这会破坏合同。

假设您有一些课程OtherLine : ILineEntity。假设此代码有效:

var list = new List<PharmaLine>();
var list2 = (IList<ILineEntity>)list; // Invalid!
list2.Add(new OtherLine()); // This should work if the cast were valid


这适用于枚举,因为PharmaLine的序列始终是ILineEntity的有效序列(协方差)。

请注意,您也可以使用IReadOnlyList<out T>,它也是协变的,但是缺少可用来修改列表的方法。

09-28 04:45