2013-02-22 77 views
8

我可以隱式地將一個int轉換爲IComparable。我也可以將List或數組轉換爲IEnumerable。List <int> to IEnumerable <IComparable>

但爲什麼我不能隱式地將一個列表轉換爲IEnumerable?

我用.net framework 4.5和Visual Studio 2012 Ultimate測試了這個。

代碼來測試:

IComparable test1; 
int t1 = 5; 
test1 = t1; //OK 

IEnumerable<int> test2; 
List<int> t2 = new List<int>(); 
int[] t3 = new int[] { 5, 6 }; 
test2 = t2; //OK 
test2 = t3; //OK 

TabAlignment[] test; 

IEnumerable<IComparable> test3; 
test3 = t2; //error Cannot implicitly convert type 'System.Collections.Generic.List<int>' to 'System.Collections.Generic.IEnumerable<System.IComparable>'. An explicit conversion exists (are you missing a cast?) 

回答

12

通用方差並不適用於價值類型,基本上是這樣。所以,當你可以

你需要框中的每個值:

IEnumerable<IComparable> test3 = t2.Cast<IComparable>(); 

因此,雖然這是有效的,因爲string是引用類型:

List<string> strings = new List<string>(); 
IEnumerable<IComparable> comparables = strings; 

...等效對List<int>不起作用,您需要隨身攜帶。

+0

已經通過你的答案閱讀,並與我的(再測試在代碼中),我意識到我在這個實例中是錯誤的,因爲它處理List - > List而不是List - > IEnumerable的轉換,但我很困惑爲什麼這會有所作爲。你可以解釋嗎? – 2013-02-22 17:11:42

+0

@JonEgerton:我懷疑你在該評論中放置了泛型類型參數,但是我看不到它們。再試一次,用反斜槓代碼相關的位。 – 2013-02-22 17:21:20

+1

@JonEgerton:好的,閱讀你的答案,然後再次評論...... - 這是因爲'List '不是'T'中的協變,而是'IEnuemrable '(從.NET 4開始)。類永遠不會是變體。在MSDN上搜索「通用方差」以獲取更多詳細信息:) – 2013-02-22 17:24:19

2

它與泛型列表的一個共同的困惑,但基本上如果你概括它更有意義:

考慮此設置:

public interface IA{ 
} 

public class A : IA{ 
} 

var listA = new List<A>(); 

下面一行是行不通的:

List<IA> listI = ListA; 

基本上這是因爲,即使A : IAList<I> does not : List<A> - 它們是完全獨立的類型。

你可以做演員很輕鬆了,雖然使用Cast方法:

listI = ListA.Cast<IA>(); 

所以你的情況,你可以做

test3 = t2.Cast<IComparable>(); 
相關問題