繁体   English   中英

为什么我不能将List <List <Foo >>传递给IEnumerable <IEnumerable <Foo >>

[英]Why can't I pass a List<List<Foo>> to an IEnumerable<IEnumerable<Foo>>

此代码生成两个编译时错误:

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组件有什么不同?

编辑:我刚刚意识到我还没有真正回答如何解决限制的问题。 幸运的是,这很容易:

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;

接口(或委托)必须声明类型参数本身的方差,因此如果您查看IEnumerable<T>的.NET 4 文档,您将看到它被声明为

public interface IEnumerable<out T>

其中, out声明的协方差T

埃里克利珀有很多在他的博客类别详细了解此协方差和逆变

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM