c#基类作为参数类型

本文关键字:参数 类型 基类 | 更新日期: 2023-09-27 17:49:19

我有两个类如下,类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'转换为'System.Collections.Generic.List'

这应该不工作,因为B只是从A继承,并将具有A的属性?

我已经花了几个小时来查这个,但我还没有弄清楚我做错了什么。我该怎么修理它?

c#基类作为参数类型

不应该。有潜在的不安全:

class C : A {
}
public static void Get(List<A> values)
{
    values.Add(new C());
}

如果你用new List<B>()调用Get,这将是不安全的,因为你将在List<B>中插入C的实例。

但是,如果List<T>是一个"只读"接口,那么协方差将是安全的,这是您正在寻找的。你可以把List<A>改为IEnumerable<A>,这样就可以了。

虽然B可以用在任何A可以用的地方,但List<B>List<A>不是协变。然而,从。net 4.0开始,你可以使用Derived类的列表来代替IEnumerable<Base>。因此,如果您声明函数接受IEnumerable<A>而不是List<A>,那么您的代码将可以编译。

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