I just got this quiz from a colleague that is driving me crazy. For this snippet of code:
var x = new Int32?();
string text = x.ToString(); // No exception
Console.WriteLine(text);
Type type = x.GetType(); // Bang!
Why does the first part .ToString() works without throwing an exception and then the call to GetType() throws a NullReferenceException ?
ToString
is overridden in Nullable<T>
, so no boxing is involved to make the call.
GetType()
isn't a virtual method, so isn't (and can't be) overridden, so the value is boxed before the call is made... and boxing a null value of a nullable value type gives a null reference.
The reason for boxing is in section 7.5.5 of the C# 4 spec:
If
M
is an instance function member declared in a reference-type:
- ...
- If the type of
E
is a value-type, a boxing conversion (4.3.1) is performed to convertE
to typeobject
, andE
is considered to be of typeobject
in the following steps. In this case,M
could only be a member ofSystem.Object
Note that if you had:
var x = new Int32?(10);
you'd end up with the type being the same as typeof(int)
, again due to boxing. There is no way of creating a value foo
such that foo.GetType()
returns a nullable value type, using the normal GetType()
method. (You could create a new GetType()
method of course, but that's a side issue :)
(The use of "Bang!" suggests the author of said quiz may be me. Apologies for driving you crazy if that's the case.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With