C# 如何将类列表传递到接口列表?

C# 如何将类列表传递到接口列表?,c#,class,list,interface,C#,Class,List,Interface,我有这样一个函数: DoSomething(List<IMyInterface>) IMyInterface是一个接口,MyClass是实现该接口的类 类MyClass:IMyInterface 我称之为DoSomethingList,它看起来不起作用。 如何将类的列表作为函数的参数传递给类接口的列表?谢谢 如果您的代码只是在方法内部的序列上迭代,而不是添加、删除或按索引访问,请将您的方法更改为以下方法之一 DoSomething(IEnumerable<IMyInterfa

我有这样一个函数:

DoSomething(List<IMyInterface>)
IMyInterface是一个接口,MyClass是实现该接口的类 类MyClass:IMyInterface

我称之为DoSomethingList,它看起来不起作用。
如何将类的列表作为函数的参数传递给类接口的列表?谢谢

如果您的代码只是在方法内部的序列上迭代,而不是添加、删除或按索引访问,请将您的方法更改为以下方法之一

DoSomething(IEnumerable<IMyInterface> sequence)
DoSomething<T>(IEnumerable<T> sequence) where T : IMyInterface
IEnumerable接口在.NET4第一个选项中是协变的。或者,如果使用C3,则可以使用后一个签名

否则,如果需要索引操作,请在传递列表之前对其进行转换。在调用中,您可能已经

// 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
后一个签名允许您做的是还支持添加或删除在callsite可见的列表,并且它还允许您使用列表而无需首先复制它


即使如此,如果您所做的只是在循环中对列表进行迭代,我还是希望使用一种接受IEnumerable的方法

这通常是不安全的,因为列表是可变的。假设您将对列表的引用作为列表传递给某人,那么他们会:

void Foo(List<IMyInterface> list)
{
    IMyInterface x = new MyOtherClassWhichAlsoImplementsIMyInterface();
    list.Add(x);
}
现在,您的列表包含一个不是MyClass的类的实例。这将违反类型安全性。正如其他答案所指出的,您可以通过只传递List的IEnumerable接口来避免这个问题,该接口提供只读访问,因此是安全的


有关更多详细信息,请参阅。另请参见。

如果只需要查看列表,请使用IEnumerable声明该方法。如果您想向列表中添加元素,那么您所要求的不是类型安全的,因此在C中可能不被允许。

对于索引操作和删除,DoSomethingIList列表中的t:IMyInterface是否也起作用?不需要复制列表。@Sli,是的,他可以使该方法通用。我已经更新了以显示通用选项。另一种方法是定义一个接口IReadableList,然后编写一个包装器类来实现它和IList。但不幸的是,其他代码必须更改才能使用包装器类。可以定义从列表到ListWrapper的扩展转换,但这有点令人讨厌,并且不能帮助系统认识到列表可以转换为实现IReadableList的ListWrapper。