如何将类的列表传递给接口的列表
本文关键字:列表 接口 | 更新日期: 2023-09-27 18:10:27
我有一个这样的函数:
DoSomething(List<IMyInterface>)
IMyInterface是一个接口,MyClass是实现这个接口的类MyClass类:IMyInterface
我调用DoSomething(List<MyClass>)
,它看起来不起作用。我如何将类的列表传递给类的接口列表作为函数的参数?谢谢!
如果您的代码只是在方法内部的序列上迭代(不通过索引添加、删除或访问),请将您的方法更改为以下之一
DoSomething(IEnumerable<IMyInterface> sequence)
DoSomething<T>(IEnumerable<T> sequence) where T : IMyInterface
IEnumerable<>
接口是协变的(从。net 4开始)(第一个选项)。如果使用c# 3,也可以使用后一种签名。
否则,如果需要索引操作,请在传递列表之前对其进行转换。在调用中,可能有
// invocation using existing method signature
DoSomething(yourList.Cast<IMyInterface>().ToList());
// or updating method signature to make it generic
DoSomething<T>(IList<T> list) where T : IMyInterface
后一个签名将允许您做的是还支持向列表添加或删除(在调用站点中可见),并且它还允许您使用列表而无需首先复制它。
即使如此,如果你所做的只是在循环中遍历列表,我还是倾向于接受IEnumerable<>
的方法。
这通常是不安全的,因为列表是可变的。假设您将对List<MyClass>
的引用作为List<IMyInterface>
传递给某人,那么他们会这样做:
void Foo(List<IMyInterface> list)
{
IMyInterface x = new MyOtherClassWhichAlsoImplementsIMyInterface();
list.Add(x);
}
现在你的List<MyClass>
包含一个类的实例,而不是MyClass
。这将违反类型安全。(正如其他答案所指出的,您可以通过仅传递List的IEnumerable<>
接口来避免此问题,该接口提供只读访问,因此是安全的)
有关更多详细信息,请参见在MSDN上的泛型集合的接口中使用方差。参见协方差和逆变以及支持协方差和逆变的各种c#特性的总结。
如果您只需要遍历列表,则使用IEnumerable声明该方法。如果你想向列表中添加元素,你所要求的不是类型安全的,因此在c#中可能不允许。