将类的List传递给方法,并将抽象基类的列表作为参数

时间:2017-10-28 13:06:57

标签: c#

我有从抽象基类继承的类,我想将这些类中的任何一个List传递给一个基类为List的方法作为参数。我怎么能做到这一点?

这是我想要的 -

public abstract class MyBaseClass {}

public class MyClass1 : MyBaseClass {}

//Inside another class
public void MyMethod(List<MyBaseClass> listOfBaseClass){}

//Inside another class
List<MyClass1> myClass1List = new List<MyClass1>();
MyMethod(myClass1List); //ERROR HERE, This method call does not compile

无论如何要完成我想要做的事情吗?

2 个答案:

答案 0 :(得分:3)

如果您想传递MyBaseClass的派生类型集合,则需要更改签名

public void MyMethod(List<MyBaseClass> listOfBaseClass){}

支持协方差的类型,例如IEnumerableIReadOnlyCollection,例如:

public void MyMethod(IEnumerable<MyBaseClass> listOfBaseClass){}

这是因为List是不变的,而IEnumerable是协变的。编译器严格的原因是因为List允许更改集合,例如如果MyMethod允许这样做:

public void MyMethod(List<MyBaseClass> listOfBaseClass)
{
    listOfBaseClass.Add(new AnotherClass());
}

AnotherClassMyBaseClass的另一个子类,break调用者的集合应该是List<MyClass1>();

有关this here

的更多信息

答案 1 :(得分:1)

使用IReadOnlyList<T>类型的参数声明您的方法。

您无法接收List<T>IList<T>,因为它们不是只读的。如果您可以将List<MyClass1>参数作为IList<MyBaseClass>参数传递给方法,则该方法可以尝试将MyClass2对象添加到列表中(假设MyClass2是另一个继承者MyBaseClass)。从方法的角度来看,它会没问题,但它会导致运行时失败 - 所以C#语言会立即阻止它。

如果您使用只读列表,您的问题将得到解决。例如,IReadOnlyList<MyBaseClass>类型的参数将接受List<MyClass1>类型的参数 - 因为List<T>实现IReadOnlyList<T>,而IReadOnlyList<T>T声明为{ {1}}。

通过这种方式,您不必诉诸out,也不会因索引而失去计数和随机访问权。