为啥我不能将 List<List<Foo>> 传递给 IEnumerable<IEnumerable<Foo>>
Posted
技术标签:
【中文标题】为啥我不能将 List<List<Foo>> 传递给 IEnumerable<IEnumerable<Foo>>【英文标题】:Why can't I pass a List<List<Foo>> to an IEnumerable<IEnumerable<Foo>>为什么我不能将 List<List<Foo>> 传递给 IEnumerable<IEnumerable<Foo>> 【发布时间】:2012-01-25 10:09:59 【问题描述】:此代码生成两个编译时错误:
private void DoSomething()
List<List<Foo>> myFoos = GetFoos();
UseFoos(myFoos);
private void UseFoos(IEnumerable<IEnumerable<Foo>>)
The best overloaded method match for 'NameSpace.Class.UseFoos(System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<Foo>>)' has some invalid arguments
和
Argument 1: cannot convert from 'System.Collections.Generic.List<System.Collections.Generic.List<Foo>>' to 'System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<Foo>>'
投射到IEnumberable<List<Foo>>
不是问题。强制转换失败类型的内部 List
组件有什么不同?
【问题讨论】:
你是 C# 4.0 之前的版本吗? ***.com/questions/1280332/… 和 ***.com/questions/730401/upcasting-and-generic-lists 可能是相关的,如果不是完全的欺骗。 您确定您使用的是 C# 4.0? @AakashM:正确我使用的是 3.5。 @AakashM 查看这些示例中的 3.5 解决方法;除非/直到我真的需要支持内部容器不是List<>
之外的东西,我想我会通过的。实现都属于丑陋和明显性检查。
【参考方案1】:
编辑:我刚刚意识到我还没有真正回答如何解决这个限制的问题。幸运的是,这很容易:
UseFoos(myFoos.Cast<IEnumerable<Foo>>());
该代码在 C# 4 下编译良好(当您为 UseFoos
参数指定名称时),它为接口和委托引入了泛型协变和逆变。
作为一个更简单的示例,这在 C# 4 中有效,但在 C# 3 中无效:
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
请注意,即使在 C# 4 中,类也不是一成不变的,所以这不起作用:
// This won't work
List<string> strings = new List<string>();
List<object> objects = strings;
...即使是接口,也只有在安全的情况下才支持:
// This won't work either
IList<string> strings = new List<string>();
IList<object> objects = strings;
接口(或委托)必须声明类型参数本身的变化,因此如果您查看 .NET 4 documentation for IEnumerable<T>
,您会看到它被声明为
public interface IEnumerable<out T>
其中out
声明了T
中的协方差。
Eric Lippert 在他的covariance and contravariance 博客类别中有更多关于此的。
【讨论】:
以上是关于为啥我不能将 List<List<Foo>> 传递给 IEnumerable<IEnumerable<Foo>>的主要内容,如果未能解决你的问题,请参考以下文章
为啥 swipeActions 修饰符不能直接与 List 容器一起使用? #SwiftUI
为啥我的 List<Foo> 不能用 protobuf-net 序列化?
为啥 std::move 不能与 std::list 一起使用
为啥我在 List<List<T>> 中复制 List<T> 时存在依赖关系? [复制]