2010-06-09 36 views
7

任何人都可以闡明爲什麼反轉不適用於C#值類型?反向代表值類型

以下不起作用

private delegate Asset AssetDelegate(int m); 

internal string DoMe() 
{ 
    AssetDelegate aw = new AssetDelegate(DelegateMethod); 
    aw(32); 
    return "Class1"; 
} 

private static House DelegateMethod(object m) 
{ 
    return null; 
} 
+1

我會發表一個答案,但我不想摸索的措辭。檢查Eric Lippert的博客條目,特別是評論。 http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx它似乎是一個具有相同內存佔用量的引用類型「值」的情況,這不是值類型的情況。有了這個說法,DelgateMethod可以變成通用的,然後支持整數,長整型等。 – 2010-06-09 14:55:59

回答

5

問題是int不是對象

一個int可以是盒裝到一個對象。結果對象(aka boxed int)當然是一個對象,但它不再是一個int。

請注意,「」我上面使用的是不相同的C#運營商is。我的「」表示「可由轉換爲隱式參考轉換」。這是當我們談論協變和逆變時使用的「」的含義。

int可以隱式轉換爲對象,但這不是參考轉換。它必須裝盒。

House通過引用轉換可以隱式轉換爲Asset。沒有必要創建或修改任何對象。

考慮下面的例子。變量houseasset都引用了相同的對象。另一方面,變量integerboxedInt保持相同的值,但它們引用不同的事物。

House house = new House(); 
Asset asset = house; 

int integer = 42; 
object boxedInt = integer; 

Boxing and Unboxing並不像看起來那麼簡單。它有許多微妙之處,並可能以意想不到的方式影響您的代碼。混合拳與協變和逆變是一個讓任何人都眩目的簡單方法。

+0

在我看來,試圖假設來自'System.Object'的值類型是沒有用的。認識到對於每個值類型都有一個從「System.ValueType」派生的關聯「盒裝」類類型是非常有用的。值類型可以隱式轉換爲它們的類類型等價物,並且可以使用顯式轉換將盒裝值類型的內容複製回真實類型。 – supercat 2012-06-26 20:28:40

1

我與安東尼Pegram的評論表示贊同 - 這是基於具有不同的內存佔用比的值類型引用類型:在CLR可以暗中使用的一類一類的它是一個超類型的類,但是當你開始使用值類型時,CLR將需要將你的整數加框,以便它可以在對象的位置工作。

如果你正在尋找讓反正它的工作,我必須包裝在聲明中表達的傾向:

AssetDelegate aw = new AssetDelegate((m) => DelegateMethod(m)); 

我不知道這是很好的做法還是不至於語法去,但請記住,拳擊和拆箱費用很高。