简体   繁体   English

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

[英]Pass a List of a class into method with list of an abstract base class as a parameter

I have classes that inherit from an abstract base class, and I want to pass a List of any of those classes into a method that that has a List of the base class as a parameter. 我有从类抽象基类继承的类,我想将任何这些类的List传递给一个方法,该方法将基类的List作为参数。 How can I make that happen? 我怎么能做到这一点?

Here is want I've tried - 这是希望我尝试过 -

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

Is there anyway to accomplish what I am trying to do? 反正有没有完成我想要做的事情?

If you want to pass collections of derived types of MyBaseClass , you'll need to change the signature 如果要传递MyBaseClass派生类型的MyBaseClass ,则需要更改签名

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

To a type which supports covariance, such as IEnumerable or IReadOnlyCollection , eg: 对于支持协方差的类型,例如IEnumerableIReadOnlyCollection ,例如:

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

This is because List is invariant, whereas IEnumerable is covariant. 这是因为List是不变的,而IEnumerable是协变的。 The reason why the compiler is strict is because List allows for change to the collection, eg if MyMethod would be allowed to do this: 编译器严格的原因是因为List允许更改集合,例如,如果允许MyMethod执行此操作:

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

Where AnotherClass was another subclass of MyBaseClass , it would break the caller's collection which was supposed to be of List<MyClass1>() ;. AnotherClass是另一个子MyBaseClass ,它会break来电者的集合,其应该是的List<MyClass1>() ;

More about this here 更多关于这里

Declare your method with a parameter of type IReadOnlyList<T> . 使用IReadOnlyList<T>类型的参数声明您的方法。

You cannot receive List<T> or IList<T> because they are not read-only. 您无法接收List<T>IList<T>因为它们不是只读的。 If you could pass a List<MyClass1> argument into a method as a IList<MyBaseClass> parameter, the method could attempt to add a MyClass2 object into the list (assuming MyClass2 is another inheritor of MyBaseClass ). 如果你可以通过一个List<MyClass1>参数转换为一个方法IList<MyBaseClass>参数,该方法可以尝试添加MyClass2对象到列表中(假设MyClass2是另一继承MyBaseClass )。 It would be OK from the method's perspective, but it would cause runtime failure - so the C# language prevents it right off. 从方法的角度来看,它会没问题,但它会导致运行时失败 - 所以C#语言会立即阻止它。

Your problem will be solved if you would use a read-only list. 如果您使用只读列表,您的问题将得到解决。 For example, a parameter of type IReadOnlyList<MyBaseClass> would accept argument of type List<MyClass1> - because List<T> implements IReadOnlyList<T> , and IReadOnlyList<T> declares T as out . 例如,类型为IReadOnlyList<MyBaseClass>参数将接受List<MyClass1>类型的参数 - 因为List<T>实现IReadOnlyList<T> ,而IReadOnlyList<T> T声明为out

In this way you don't have to resort to IEnumerable<T> , and won't lose count and random access by index. 通过这种方式,您不必使用IEnumerable<T> ,也不会丢失索引的计数和随机访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM