簡體   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