我正在尝试将一个列表传递给一个列表的DerivedClass函数BaseClass,但是我得到了错误:
cannot convert from 
'System.Collections.Generic.List<ConsoleApplication1.DerivedClass>' 
to 
'System.Collections.Generic.List<ConsoleApplication1.BaseClass>'
现在我可以把我List<DerivedClass>投入到一个List<BaseClass>,但我不觉得这样做,除非我理解为什么编译器不允许这样做.  
我发现的解释只是说它以某种方式违反了类型安全,但我没有看到它.谁能帮我吗?
什么是编译器允许从转换的风险List<DerivedClass>来List<BaseClass>?
这是我的SSCCE:
class Program
{
    public static void Main()
    {
        BaseClass bc = new DerivedClass(); // works fine
        List<BaseClass> bcl = new List<DerivedClass>(); // this line has an error
        doSomething(new List<DerivedClass>()); // this line has an error
    }
    public void doSomething(List<BaseClass> bc)
    {
        // do something with bc
    }
}
class BaseClass
{
}
class DerivedClass : BaseClass
{
}
cuo*_*gle 49
这是因为List<T>是in-variant,不是co-variant,所以你应该更改为IEnumerable<T>支持co-variant,它应该工作:
IEnumerable<BaseClass> bcl = new List<DerivedClass>();
public void doSomething(IEnumerable<BaseClass> bc)
{
    // do something with bc
}
关于通用的共变体的信息
Eri*_*ert 44
我发现的解释只是说它以某种方式违反了类型安全,但我没有看到它.什么是编译器允许从转换的风险
List<DerivedClass>来List<BaseClass>?
几乎每天都会问这个问题.
A List<Mammal>无法转换为a,List<Animal>因为您可以将蜥蜴放入动物列表中.A List<Mammal>无法转换为a,List<Giraffe>因为列表中可能已有老虎.
因此List<T>必须在T中保持不变.
但是,List<Mammal>可以转换为IEnumerable<Animal>(从C#4.0开始),因为没有方法IEnumerable<Animal>可以添加蜥蜴.在T.中IEnumerable<T>是协变的
SLa*_*aks 13
您描述的行为称为协方差 - 如果A 是 B,那么List<A> 就是 List<B>.
但是,对于可变类型List<T>,这基本上是不安全的.
如果这是可能的,该方法将能够添加new OtherDerivedClass()到实际上只能保持的列表DerivedClass.
协方差在不可变类型上是安全的,尽管.Net仅在接口和委托中支持它.
如果您将List<T>参数更改为IEnumerable<T>,那将起作用
| 归档时间: | 
 | 
| 查看次数: | 18260 次 | 
| 最近记录: |