我有从抽象基类继承的类,我想将这些类中的任何一个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
无论如何要完成我想要做的事情吗?
答案 0 :(得分:3)
如果您想传递MyBaseClass
的派生类型集合,则需要更改签名
public void MyMethod(List<MyBaseClass> listOfBaseClass){}
支持协方差的类型,例如IEnumerable
或IReadOnlyCollection
,例如:
public void MyMethod(IEnumerable<MyBaseClass> listOfBaseClass){}
这是因为List
是不变的,而IEnumerable
是协变的。编译器严格的原因是因为List
允许更改集合,例如如果MyMethod
允许这样做:
public void MyMethod(List<MyBaseClass> listOfBaseClass)
{
listOfBaseClass.Add(new AnotherClass());
}
AnotherClass
是MyBaseClass
的另一个子类,break
调用者的集合应该是List<MyClass1>()
;
答案 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
,也不会因索引而失去计数和随机访问权。