class C<T> where T : struct {
bool M1(object o) => o is T;
bool M2(object o) => o is T?;
}
The two methods above seems to behave equally, both when passing null
reference or boxed T
value. However, the generated MSIL code is a bit different:
.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
}
vs
.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
}
As you may see, the o is T?
expression actually performs type check for Nullable<T>
type, despite the fact that nullable types are specially handled by CLR so that C# represents boxed T?
value as null
reference (if T?
has no value) or boxed T
value. It seems impossible to get box of Nullable<T>
type in pure C# or maybe even in C++/CLI (since runtime handles box
opcode to support this "T?
=> T
box / null
" boxing).
Am I missing something or o is T?
is practically equivalent to o is T
in C#?
Nullable<T>
object. Please fix your question so it's actually clear what you're trying to find out. – Lessoro is T?
is practically equivalent too is T
in C#", it is as clear as it can be :) – NostomaniaM2()
will ever returntrue
, so it doesn't seem practical to me, nor equivalent. – Lessoris
in C# gets compiled toisinst
in CIL for both types, on the basis thatNullable<T>
is specially handled by the CLR? That is exactly the reason why it gets compiled to the same thing, so the C# compiler doesn't have to handle nullable shenanigans. – Towery