如何将类列表传递给接口列表?

sps*_*pli 24 c# interface class list

我有这样的功能:

DoSomething(List<IMyInterface>)
Run Code Online (Sandbox Code Playgroud)

IMyInterface是一个接口,MyClass是一个实现此接口的类MyClass:IMyInterface

我打电话DoSomething(List<MyClass>),它看起来不起作用.我怎样才能将类的列表作为函数的参数传递给类的接口列表?谢谢!

Ant*_*ram 35

如果您的代码只是迭代方法内的序列(不是通过索引添加,删除或访问),请将您的方法更改为以下之一

DoSomething(IEnumerable<IMyInterface> sequence)
DoSomething<T>(IEnumerable<T> sequence) where T : IMyInterface
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

后一个签名允许您执行的操作是还支持添加或删除列表(在调用点上可见),并且它还允许您在不先复制它的情况下使用该列表.

即使如此,如果你所做的只是循环遍历列表,我会赞成一个方法加入IEnumerable<>.

  • 对于索引操作和删除,Do:Something &lt;T&gt;(IList &lt;T&gt; list)在T:IMyInterface`上也可以吗?(无需复制列表。) (2认同)

D C*_*zee 13

这通常是不安全的,因为列表是可变的.假设你通过一个人一个参考的List<MyClass>作为List<IMyInterface>,那么,他们这样做:

void Foo(List<IMyInterface> list)
{
    IMyInterface x = new MyOtherClassWhichAlsoImplementsIMyInterface();
    list.Add(x);
}
Run Code Online (Sandbox Code Playgroud)

现在你List<MyClass>包含一个不是a的类的实例MyClass.这会违反类型安全.(正如其他答案所述,您可以通过仅传递IEnumerable<>List 的接口来避免此问题,该接口提供只读访问权限,因此是安全的).

有关更多详细信息,请参阅在MSDN上使用接口中的通用集合的方差.另请参阅协方差和逆变的一个很好的总结以及支持它的各种C#功能.