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

本文关键字:列表 接口 | 更新日期: 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#中可能不允许。