.method private hidebysig instance void Insert(!TKey key, !TValue'value', bool add ) cil managed
{
.maxstack 3
.locals init (
[0] int32 num,
[1] int32 num2,
[2] int32 num3,
[3] int32 num4)
L_0000: ldarg.1
L_0001: box !TKey
L_0006: brtrue.s L_000e
L_0008: ldc.i4 .5
L_0009: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument)
This is the internal Add method from Dictionary
Edit: Marc’s answer to this particular question summary: The important reason is This dictionary
The key here is required to be not empty; So it does need to be verified.
In fact, boxing is not as bad as people think; even if it is boxed, gen-0 will be collected. It can pass generics (e.g. EqualityComparer
JIT can also remove null checks. I can say here that although this is often quoted, I have seen invalid checks go beyond JIT Delete ability.
For example:
.method private hidebysig instance void Insert(!TKey key , !TValue'value', bool add) cil managed
{
.maxstack 3
.locals init (
[0] int32 num,
[1] int32 num2,
[2] int32 num3,
[3] int32 num4)
L_0000: ldarg.1
L_0001: box !TKey
L_0006: brtrue.s L_000e
L_0008: ldc.i4.5
L_0009: call void System.ThrowHelp er::ThrowArgumentNullException(valuetype System.ExceptionArgument)
This is the internal Add method from Dictionary
Edit: Marc’s answer to this particular question summary: The important reason is This dictionary
Nullable< T> is a struct / value-type, which can be null (depending on your definition of null; but certainly it can be null ). Not all TKeys are value types (strings are probably the most common TKey).
The key here is required to be non-empty; so it does need to be verified.
Actually, boxing is not as bad as people think; even if it is boxed, gen-0 will be collected. It can be used for special cases through generics (e.g. EqualityComparer
JIT can also delete empty checks. I can say here that although this is often quoted, I have seen cases where invalid checks exceed the ability of JIT to delete.