The bit I am interested in is the ‘is’ operator which translates to ‘isinst’ in IL_0008:

IL_0008: isinst valuetype [mscorlib]System.Nullable`1<int32>

Let’s have a look at ‘isinst’ from CIL Instruction Set document. The specification uses ‘isinst typeTok’ as the format of the instruction and below is description from the spec (emphasis mine):

“typeTok is a metadata token (a typeref, typedef or typespec), indicating the desired class. If typeTok is a non-nullable value type or a generic parameter type it is interpreted as ‘boxed’ typeTok. If typeTok is a nullable type, Nullable<T>, it is interpreted as ‘boxed’ T.”

The last bit is interesting; so the result of isinst depends on how boxing works for Nullable types. Well, let’s have a look at boxing then. First a little bit of code to see how the ToInt method is typically called:

int? input = 12;
Console.WriteLine(input.ToInt());

You would typically have a nullable int that you pass to ToInt (you may also pass other types in; but that is not very important in our case). Let’s have a look at the a bit of IL for the above snippet:

As expected, we are calling ‘box’ IL instruction (at IL_000c) on the input variable. Let’s have a look at ‘box’ instruction from CIL specification. The format is ‘box typeTok’ (emphasis mine):

“If typeTok is a value type, the box instruction converts val to its boxed form. When typeTok is a non-nullable type (§I.8.2.4), this is done by creating a new object and copying the data from val into the newly allocated object. If it is a nullable type, this is done by inspecting val’s HasValue property; if it is false, a null reference is pushed onto the stack; otherwise, the result of boxing val’s Value property is pushed onto the stack.”

Alternative implementations of ToInt method###

So for nullable types, after boxing, which is the case for object input parameter, we either get null or an int value! So we could actually write the ToInt method as: