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

发布于 2024-12-08 00:37:32 字数 255 浏览 1 评论 0原文

我有一个这样的函数:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

伴我心暖 2024-12-15 00:37:32

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

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<> 的方法。

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

DoSomething(IEnumerable<IMyInterface> sequence)
DoSomething<T>(IEnumerable<T> sequence) where T : IMyInterface

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

// 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

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<>.

风流物 2024-12-15 00:37:32

一般来说,这并不安全,因为列表是可变的。假设您将 List 的引用作为 List 传递给某人,那么他们会执行以下操作:

void Foo(List<IMyInterface> list)
{
    IMyInterface x = new MyOtherClassWhichAlsoImplementsIMyInterface();
    list.Add(x);
}

现在是您的 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 a List<IMyInterface>, then they do:

void Foo(List<IMyInterface> list)
{
    IMyInterface x = new MyOtherClassWhichAlsoImplementsIMyInterface();
    list.Add(x);
}

Now your List<MyClass> contains an instance of a class that is not a MyClass. This would violate type safety. (As other answers noted, you can avoid this problem by passing only the IEnumerable<> 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.

娇纵 2024-12-15 00:37:32

如果您只需要遍历列表,请使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文