class C<T> where T : struct {
bool M1(object o) => o is T;
bool M2(object o) => o is T?;
}
Два вышеприведенных метода ведут себя одинаково, как при передаче null
reference, так и в боксе T
. Однако сгенерированный код MSIL немного отличается:
.method private hidebysig instance bool M1(object o) cil managed {
.maxstack 8
IL_0000: ldarg.1
IL_0001: isinst !T
IL_0006: ldnull
IL_0007: cgt.un
IL_0009: ret
}
против
.method private hidebysig instance bool M2(object o) cil managed {
.maxstack 8
IL_0000: ldarg.1
IL_0001: isinst valuetype [mscorlib]System.Nullable`1<!T>
IL_0006: ldnull
IL_0007: cgt.un
IL_0009: ret
}
Как вы можете видеть, выражение o is T?
фактически выполняет проверку типа для типа Nullable<T>
, несмотря на то, что типы с нулевым значением специально обрабатываются с помощью CLR, так что С# представляет значение в коробке T?
как null
reference (if T?
не имеет значения) или значение в коробке T
. Кажется невозможным получить поле типа Nullable<T>
в чистом С# или, возможно, даже в С++/CLI (поскольку runtime обрабатывает код операции box
для поддержки этого "T?
= > T
box/null
" бокса).
Я что-то упустил или o is T?
практически эквивалентен o is T
в С#?