c#基类作为参数类型

时间:2012-12-22 03:04:58

标签: c#

我有两个类,如下所示,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具有的属性?

我已经花了好几个小时试图查看这个但是没有弄清楚我做错了什么,请帮帮忙。

3 个答案:

答案 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);
  }