ECMA-335,1.8.2.4指定了可包裝類型包括引用類型(不包括託管指針/ byrefs)和通用參數。爲什麼拳擊參考類型?
拳擊參考類型的目的是什麼?盒裝參考對象的功能和內存表示與非盒裝的參考對象有什麼不同?
ECMA-335,1.8.2.4指定了可包裝類型包括引用類型(不包括託管指針/ byrefs)和通用參數。爲什麼拳擊參考類型?
拳擊參考類型的目的是什麼?盒裝參考對象的功能和內存表示與非盒裝的參考對象有什麼不同?
裝箱引用類型引用沒有任何邏輯錯誤。這只是一個沒有操作,沒有任何改變。
但是Ecma-335並不總是一個很好的描述,它是在.NET CLR中實現的真正的。實現Opcodes.Box的JIT_Box()輔助函數實際上會在要求輸入非值類型的值時拋出InvalidCastException。它期望編譯器和抖動知道何時在不需要時抑制裝箱轉換。他們是這樣。
但它確實接受表示引用類型的通用參數而不引發異常。在這種情況下,無操作行爲需要支持從'T'到'object'的投射。 – CodesInChaos
這是一個有效的觀點。抖動已經知道T是一個參考類型,完全省略了用於裝箱轉換的代碼。 –
您是否在正常參考類型上使用'box'時檢查它是否實際拋出?也許在這種情況下,JITter在達到異常拋出代碼之前優化它。 – CodesInChaos
考慮泛型函數:
object MyBox<T>(T value)
{
return (object)value;
}
這編譯爲:
ldarg.1
box 01 00 00 1B
ret
此功能的預期行爲是一個空操作,如果T
是引用類型,值拳擊本身。
裝箱一個知道是引用類型的值沒那麼有用,但是以與泛型一致的方式指定它是簡單和一致的。
.NET允許引用類型被裝箱,但C#不允許。運行時允許它,但C#編譯器永遠不會利用該功能。 – Servy
@Servy,在實踐中這是如何工作的,儘管我認識到假設。它會像'var o =(object)myRefInstance;'?這很奇怪,因爲'myRefInstance'顯然已經基於'object'。 –
另外,「如果typeTok是一個引用類型,盒子指令確實返回val不變爲obj」 - III.4.1。 –