2013-10-23 108 views
6

ECMA-335,1.8.2.4指定了可包裝類型包括引用類型(不包括託管指針/ byrefs)和通用參數。爲什麼拳擊參考類型?

拳擊參考類型的目的是什麼?盒裝參考對象的功能和內存表示與非盒裝的參考對象有什麼不同?

+2

.NET允許引用類型被裝箱,但C#不允許。運行時允許它,但C#編譯器永遠不會利用該功能。 – Servy

+0

@Servy,在實踐中這是如何工作的,儘管我認識到假設。它會像'var o =(object)myRefInstance;'?這很奇怪,因爲'myRefInstance'顯然已經基於'object'。 –

+2

另外,「如果typeTok是一個引用類型,盒子指令確實返回val不變爲obj」 - III.4.1。 –

回答

5

裝箱引用類型引用沒有任何邏輯錯誤。這只是一個沒有操作,沒有任何改變。

但是Ecma-335並不總是一個很好的描述,它是在.NET CLR中實現的真正的。實現Opcodes.Box的JIT_Box()輔助函數實際上會在要求輸入非值類型的值時拋出InvalidCastException。它期望編譯器和抖動知道何時在不需要時抑制裝箱轉換。他們是這樣。

+0

但它確實接受表示引用類型的通用參數而不引發異常。在這種情況下,無操作行爲需要支持從'T'到'object'的投射。 – CodesInChaos

+0

這是一個有效的觀點。抖動已經知道T是一個參考類型,完全省略了用於裝箱轉換的代碼。 –

+0

您是否在正常參考類型上使用'box'時檢查它是否實際拋出?也許在這種情況下,JITter在達到異常拋出代碼之前優化它。 – CodesInChaos

3

考慮泛型函數:

object MyBox<T>(T value) 
{ 
    return (object)value; 
} 

這編譯爲:

ldarg.1  
box   01 00 00 1B 
ret 

此功能的預期行爲是一個空操作,如果T是引用類型,值拳擊本身。

裝箱一個知道是引用類型的值沒那麼有用,但是以與泛型一致的方式指定它是簡單和一致的。