如何将类列表传递给接口列表?
我有一个这样的函数:
DoSomething(List<IMyInterface>)
IMyInterface是一个接口,MyClass是一个实现该接口的类 Class MyClass:IMyInterface
我调用 DoSomething(List
,它看起来不起作用。 如何将类的列表作为函数的参数传递给该类的接口列表?谢谢!
I have a function like this:
DoSomething(List<IMyInterface>)
IMyInterface is an interface and MyClass is a class implementing this interface
Class MyClass:IMyInterface
I call DoSomething(List<MyClass>)
and it looks it doesn't work.
How could I pass the list of a class to a list of the interface of the class as function's parameter? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您的代码只是迭代方法内的序列(而不是添加、删除或按索引访问),请将您的方法更改为以下之一
IEnumerable<>
接口是协变的(截至.NET 4)(第一个选项)。或者,如果使用 C# 3,您可以使用后一个签名。否则,如果您需要索引操作,请在传递列表之前转换列表。在调用中,您可能有
后一个签名允许您做的就是还支持添加或删除列表(在调用站点可见),并且它还允许您使用该列表而无需先复制它。
即使如此,如果您所做的只是在循环中迭代列表,我还是倾向于使用接受
IEnumerable<>
的方法。If your code is simply iterating over the sequence inside the method (not adding, removing, or accessing by index), change your method to one of the following
The
IEnumerable<>
interface is covariant (as of .NET 4) (first option). Or you could use the latter signature if using C# 3.Otherwise, if you need indexed operations, convert the list prior to passing it. In the invocation, you might have
What the latter signature would allow you to do is to also support adds or removes to the list (visible at the callsite), and it would also let you use the list without first copying it.
Even still, if all you do is iterate over the list in a loop, I would favor a method acceping
IEnumerable<>
.一般来说,这并不安全,因为列表是可变的。假设您将
List
的引用作为List
传递给某人,那么他们会执行以下操作:现在是您的
List
包含不是MyClass
的类的实例。这会违反类型安全。 (正如其他答案所述,您可以通过仅传递 List 的 IEnumerable 接口来避免此问题,该接口提供只读访问,因此是安全的)。有关更多详细信息,请参阅在通用集合接口中使用差异MSDN。另请参阅关于协方差的一个很好的总结逆变以及支持它的各种 C# 功能。
This is not safe in general because Lists are mutable. Suppose you pass someone a reference to a
List<MyClass>
as aList<IMyInterface>
, then they do:Now your
List<MyClass>
contains an instance of a class that is not aMyClass
. This would violate type safety. (As other answers noted, you can avoid this problem by passing only theIEnumerable<>
interface of List, which provides read-only access and so is safe).For more details, see Using Variance in Interfaces for Generic Collections on MSDN. See also a good summary of covariance and contravariance and various C# features that support it.
如果您只需要遍历列表,请使用 IEnumerable 声明该方法。如果您想将元素添加到列表中,您所要求的不是类型安全的,因此在 C# 中可能不允许。
If you only need to go through the list, declare the method with an IEnumerable. If you want to add elements to the list, what you're asking isn't typesafe and might not be allowed in C# as a result.