2013-02-22 25 views
8

私はIComparableにintを暗黙的にキャストできます。リストや配列をIEnumerableにキャストすることもできます。リスト<int>から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

ジェネリック分散は基本的に、値型には適用されません。

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

...同等:stringが参照型であるため、これが有効である間、そう

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

:あなたは

あなたはそれぞれの値をボックスする必要があるだろうことができながら、だから、 List<int>では機能しません。移動するときはボックスにする必要があります。

+0

は、あなたの答えを読ん及び鉱山(その後、テストと比較したんでした私は、List - > IEnumerableではなくList - > Listからの変換を扱うので、このインスタンスでは私のことが間違っていることを理解していますが、なぜ違いがあるのでしょうか?説明できますか? –

+0

@JonEgerton:あなたはそのコメントにジェネリック型の引数を入れたと思われますが、私はそれらを見ることができません。コードに関連するビットの周りにバッククォートを付けて、もう一度試してみてください。 –

+1

@JonEgerton:答え、あなたのコメントをもう一度読んでください... 'List 'は 'T'では共変ではありませんが、' IEnuemrable 'は(.NET 4以降)です。クラスは変わることはありません。詳細についてはMSDNの "generic variance"を検索してください:) –

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>(); 
関連する問題