我有两个类,如下所示,A类继承自B类。
public class A
{
public string Title { get; set; }
}
public class B: A
{
}
然后我有一个如下的函数,它接收A类的项目列表
public static void Get(List<A> values)
{
//do something
}
现在,当我尝试将类B的项目列表传递到函数中时,如下所示
private function void Test()
{
var k = new List<B>();
Get(k);
}
我收到以下错误消息
无法转换为'System.Collections.Generic.List&lt; B&gt;'到'System.Collections.Generic.List&lt; A&gt;'
如果这不起作用,因为B只是继承自A并且具有A具有的属性?
我已经花了好几个小时试图查看这个但是没有弄清楚我做错了什么,请帮帮忙。
答案 0 :(得分:5)
不,不应该。它可能不安全:
class C : A {
}
public static void Get(List<A> values)
{
values.Add(new C());
}
如果您使用Get
致电new List<B>()
,那将是不安全的,因为您要在C
中插入List<B>
的实例。
但是,如果List<T>
是一个“只读”界面,那将是安全的,在这种情况下,你正在寻找的协方差是安全的。您可以改为将List<A>
更改为IEnumerable<A>
,然后就可以了。
答案 1 :(得分:1)
虽然B
可以在任何地方使用A
,但List<B>
和List<A>
不是covariant。但是,从.NET 4.0开始,您可以使用Derived
类的列表代替IEnumerable<Base>
。因此,如果您声明函数采用IEnumerable<A>
而非List<A>
,则代码将编译。
答案 2 :(得分:0)
B继承自A,但这并不意味着List<B>
继承自List<A>
您应该将B对象放入List<A>
并将其传递给方法。这就是多态性的全部意义所在。
private function void Test()
{
var k = new List<A>();
k.Add(new B());
k.Add(new B());
k.Add(new B());
k.Add(new B());
k.Add(new B());
k.Add(new B());
Get(k);
}