我無法找到答案以下問題:IS操作符取消裝箱值的類型與否?
object o = 10; // Box
int i = (int)o; // Unbox
很明顯,但下面不明確
bool isInt = o is int; // Is the unbox here or not?
我無法找到答案以下問題:IS操作符取消裝箱值的類型與否?
object o = 10; // Box
int i = (int)o; // Unbox
很明顯,但下面不明確
bool isInt = o is int; // Is the unbox here or not?
不,這不拆箱 - 它只是檢查是否類型是正確的。不要忘記,確實有一個對象涉及到一個類型。無論該值是否爲裝箱值類型值,檢查該類型基本上都是相同的操作。 (對於值類型或任何密封類型,可能有一些優化是可行的,因爲沒有要考慮的繼承,但基本上它仍在檢查對象頭的「類型」部分。)
檢查的一種方法是編譯該代碼,並期待在IL使用ILASM:
// object o = 10
IL_0000: ldc.i4.s 10
IL_0002: box [mscorlib]System.Int32
IL_0007: stloc.0
// int i = (int) o;
IL_0008: ldloc.0
IL_0009: unbox.any [mscorlib]System.Int32
IL_000e: stloc.1
// bool isInt = o is int
IL_000f: ldloc.0
IL_0010: isinst [mscorlib]System.Int32
所以它使用isinst
- 沒有拆箱是必要的。
不僅不需要拆箱,在邏輯上它不能。
拆箱可能成功或失敗,具體取決於對象是否確實包含我們將嘗試拆箱的類型的值。
因此,拆箱需要檢查對象是否屬於該特定類型。
因此,如果測試類型所需拆箱,然後因爲拆箱,需要測試的類型,我們就不能拆箱,直到我們會先拆箱...
因此測試類型不能要求拆箱。
從C#7開始,is
關鍵字在與模式匹配的模式匹配中獲得了新的用例。在這種情況下,拆箱確實發生e.g:
object o = 10;
if (o is int i) {
// i is the unboxed value.
}
顯然,這是一個不同的情況下,以原來的職位的其中值純粹是正在測試中,使用is
爲一種模式時一樣,你實際上是分配價值。因此在這種情況下需要取消裝箱。
要清楚 - 關於原始o is int
的情況沒有任何變化 - 根據舊的答案,不會發生拆箱。 is
關鍵字剛剛獲得新角色。
因此,CLR可以檢查類型而不拆箱? –
@ViacheslavSmityukh:是的。不要忘記,確實有一個對象涉及到一個類型。無論該值是否爲裝箱值類型值,檢查該類型基本上都是相同的操作。 –
@JonSkeet您可以將該評論編輯爲答案,我認爲解釋*爲什麼*,而不僅僅是通過IL進行證明尤其有價值。 – Servy