2013-02-22 36 views
8

Bir int içersinde bir IComparable atayabilirim. Ayrıca bir IEnumerable'a bir liste veya dizi atayabilirim.Öğe <int> IEnumerable için <IComparable>

Neden bir listeyi bir IEnumerable'a dolaylı olarak veremiyorum?

Bunu .net framework 4.5 ve Visual Studio 2012 Ultimate ile test ettim. testine

Kodu:

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?) 

cevap

12

Jenerik varyans temelde değer türleri için geçerli değildir. Yani yaparken can

Her değerini kutu gerekir: ...

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

eşdeğer: Bu geçerli iken string bir başvuru türü olduğundan Yani

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

List<int> için çalışmıyor ve gittiğinizde kutu eklemeniz gerekiyor.

public interface IA{ 
} 

public class A : IA{ 
} 

var listA = new List<A>(); 

aşağıdaki satırı işe yaramaz:

bu kurulumu düşünün: Bu jenerik listeleri ile ortak karışıklık, ama temelde bunu genellemek eğer

+0

yapabileceğini Cevabınız okuyun ve karşılaştırılmıştır benimkiyle (ve sonra test eden kodunda), List -> List'ten çok, List -> IEnumerable gibi dönüşümlerle uğraşırken, bu örnekte yanlış olanın farkına varıyorum, ancak bunun neden fark yarattığına şaşıyorum. Açıklayabilir misin? –

+0

@JonEgerton: Bu yoruma genel tür argümanları koyduğunuzu sanıyorum, ancak onları göremiyorum. Kodla ilgili bitlerin etrafındaki backticks ile tekrar deneyin. –

+1

@JonEgerton: Tamam, cevabınızı okuyorsunuz, sonra tekrar yorumunuz ... - çünkü "List ", "T" kodunda eşdeğer değil, ancak IEnuemrable '(.NET 4'ten itibaren). Sınıflar asla değişken olamaz. Daha fazla bilgi için MSDN'de "genel varyans" ara :) –

2

daha mantıklı

Esasen bunun nedeni, A : IA, List<I> does not : List<A> olsa bile - tamamen ayrı türlerdir.

Cast yöntemi kullanılarak olsa kolaylıkla yeterli döküm yapabilirsiniz

:

listI = ListA.Cast<IA>(); 

Yani durumda

test3 = t2.Cast<IComparable>(); 
İlgili konular