2010-04-28 57 views
13

已經定義了這個接口:問題有關C#4.0的泛型協方差

public interface IInputBoxService<out T> { 
    bool ShowDialog(); 
    T Result { get; } 
} 

爲什麼下面的代碼工作:

public class StringInputBoxService : IInputBoxService<string> { 
    ... 
} 

... 

IInputBoxService<object> service = new StringInputBoxService(); 

,這不?:

public class IntegerInputBoxService : IInputBoxService<int> { 
    ... 
} 

... 

IInputBoxService<object> service = new IntegerInputBoxService(); 

它與int是一個值類型有什麼關係?如果是的話,我怎樣才能繞過這種情況?

感謝

+0

您是否嘗試過使用的Int32 – Strelok 2010-04-28 06:41:41

+1

沒有,但是從我的理解這會導致同樣的int是隻是一個別名:因爲這可以很簡單? Int32。 – 2010-04-28 06:45:50

回答

14

是的,它絕對有int是值類型做。 C#4中的通用差異僅適用於引用類型。這主要是因爲引用總是具有相同的表示形式:引用只是一個引用,所以CLR可以使用相同的位來表示它所知道的某個對象引用的字符串引用。 CLR可以確保代碼是安全的,並且使用本地代碼,當傳遞IInputBoxService<string>時只知道IInputBoxService<object> - 從Result返回的值將在代表性上兼容(如果存在這樣一個術語!)。

隨着int =>object將不得不拳擊等,所以你不會結束了相同的代碼 - 基本上彌補方差。

編輯:C#4.0規範說這部分13.1.3.2:

方差註釋的目的是 提供更寬鬆的(但仍 類型安全)轉換接口 和委託類型。爲此的 定義隱式的(第6.1節)並 顯式轉換(§6.2)使 方差 - 兌換,這是 定義的概念的使用 如下:A類型T是方差 - 轉換爲一個類型 ■如果T爲一個 接口或與所述變體類型參數T中聲明 委託類型,並且對於每個變體類型 參數僖以下 之一成立:

  • Xi爲協變和 隱參考或身份 轉換從艾到碧

  • 僖 是逆變和隱式 引用或標識轉換 存在選自Bi艾

  • 僖是不變 和身份轉換存在從 艾到碧

    存在

這並不是非常明顯,但基本上參考轉換隻存在補間參考類型,只保留身份轉換(即從一個類型到它自己)。

至於解決方法:我認爲你必須創建自己的包裝類,基本上。

public class Wrapper<T> 
{ 
    public T Value { get; private set; } 
    public Wrapper(T value) 
    { 
     Value = value; 
    } 
} 

這是很討厭的,雖然:(

+0

我在想這種情況,但我找不到引用。你知道有任何msdn鏈接提到差異僅適用於引用類型嗎? – 2010-04-28 06:40:05

+0

這個怎麼樣?http://blogs.msdn。 com/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx - 使用Ctrl + F查找「需要記住的幾條重要規則」,你會找到該條目 – 2010-04-28 06:43:37

+0

有沒有其他的選擇Java爲所有人定義原始類型引用類型太多,所以而不是做某事我可以使它,這將解決這個問題。 – 2010-04-28 06:44:26