Giving the following IsNull method:
public class Field<T>
{
public static bool IsNull(T value) => value is null; // or: => value == null;
}
Is there any boxing when T is a value type? If the answer is yes, how can it be implemented without boxing? Edit: It should handle nullable type such as int? correctly.
Edit2:
Using ILDASM shows there is boxing for value is null and value == null:
.method public hidebysig static bool IsNull(!T 'value') cil managed
{
// Code size 15 (0xf)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: box !T
IL_0007: ldnull
IL_0008: ceq
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
} // end of method Field`1::IsNull
However, the following code:
public class Field
{
public static bool IsNull(int? value)
{
return value == null;
}
}
will be compiled to the following without boxing:
.method public hidebysig static bool IsNull(valuetype [System.Runtime]System.Nullable`1<int32> 'value') cil managed
{
// Code size 16 (0x10)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarga.s 'value'
IL_0003: call instance bool valuetype [System.Runtime]System.Nullable`1<int32>::get_HasValue()
IL_0008: ldc.i4.0
IL_0009: ceq
IL_000b: stloc.0
IL_000c: br.s IL_000e
IL_000e: ldloc.0
IL_000f: ret
} // end of method Field::IsNull
So the compiler does treat Nullable<> specially but not in a generic class context.