2010-06-14 100 views
0

任何人都可以告訴我爲什麼這不起作用嗎?我會認爲這個約束會使它有效。c#泛型問題

public class ClassA<T> where T : ICommon 
{ 
    public ClassA() 
    { 
     ClassB b = new ClassB(); 
     IEnumerable<T> alist = new List<T>; 
     b.Items = alist; 
     //Error: cannot convert from IEnumerable<T> to IEnumerable<ICommon>' 
    } 

} 


public class ClassB 
{ 
    public IEnumerable<ICommon> Items { get; set;} 
    .... 
} 

回答

12

這將工作在C#4與一個調整,但不是在C#3你所要尋找的是通用方差,這已在自.NET 2.0的CLR得到支持,但不是在C#直到第4版。

即使在C#4中,您也需要將T約束爲引用類型 - 因爲協方差不適用於值類型。例如,即使int實施IComparableList<int>也不能轉換爲IEnumerable<IComparable>

已經優化了你的代碼位(有幾個錯別字,有效的),這個編譯與C#4編譯:

using System.Collections.Generic; 

public interface ICommon {} 

// Note the "class" part of the constraint 
public class ClassA<T> where T : class, ICommon 
{ 
    public ClassA() 
    { 
     ClassB b = new ClassB(); 
     IEnumerable<T> alist = new List<T>(); 
     b.Items = alist; 
    } 
} 

public class ClassB 
{ 
    public IEnumerable<ICommon> Items { get; set;} 
} 

如果您是滯留在C#3和.NET 3.5,替代是使用Cast<T>()

b.Items = alist.Cast<ICommon>(); 
+0

有趣的是,由於

試試吧! (現在我的代碼已經整理好了,先生;) - 沒有智能感覺的尷尬馬虎!) – UpTheCreek 2010-06-14 10:46:18

3

這就是所謂的協方差(?或反我不知道),並且僅在C#4.0的工作。
您不能投IEnumerable<Common>IEnumerable<ICommon>。 (當通用實現ICommon。)使用

b.items = from f in alist select (T)f;