I was looking into nullable bools when I found this article on Microsoft MSDN
How to: Identify a Nullable Type (C# Programming Guide)
You can use the C# typeof operator to create a Type object that represents a Nullable type.
So I tried checking with a nullable bool:
Console.Write(typeof(bool?)); //System.Nullable`1[System.Boolean]
The article on MSDN says
You can also use the classes and methods of the System.Reflection namespace to generate Type objects that represent Nullable types. However, if you try to obtain type information from Nullable variables at runtime by using the GetType method or the is operator, the result is a Type object that represents the underlying type, not the Nullable type itself.
Calling GetType on a Nullable type causes a boxing operation to be performed when the type is implicitly converted to Object. Therefore GetType always returns a Type object that represents the underlying type, not the Nullable type.
If this is true I expect to get the same result from .GetType()
whether I use a nullable bool or a regular bool. But this is not what happens:
bool a = new bool();
Console.Write(a.GetType()); //Prints System.Boolean
bool? b = new bool?();
Console.Write(b.GetType()); //Exception!
The exception that occured:
An unhandled exception of type 'System.NullReferenceException' occurred in BoolTest.exe
Additional information: Object reference not set to an instance of an object.
But the object reference is set to an instance of an object. What could be the cause of this error?
You're calling
GetType
on aNULL
Reference (The result of boxing a Nullable Type with No Value).bool? b = new bool?();
is equivalent tobool? b = null;
Try this to get the correct result:
The documentation means that if you call
GetType()
successfully on aNullable
object that has value (Not Null). You get the Underlying type which isSystem.Boolean
. But you can't call any method using aNULL
reference and this is a general rule that applying to any reference type.To clear the equivalence point between
= null
andnew bool?()
, check this Fiddle. Both generates the same IL:and
Your actual question seems to be:
Well, yes and no.
Nullable<T>
is kind of special. From the C# specs:So yes,
bool? b = new bool?();
does return an instance: one you only can callHasValue
on. Since it returnsfalse
, you can't do much else with that instance.Then the next relevant section:
This is also explained in MSDN: Boxing Nullable Types (C# Programming Guide):
Somewhat further into the specs:
GetType()
is not overridden byNullable<T>
, so boxing will occur. When you callGetType()
or any non-overridden method on a struct, the struct will be boxed to an object before calling that method. In the case of a nullNullable<T>
, the result of that boxing operation will be(object)null
. Hence the exception.See also Does calling a method on a value type result in boxing in .NET?.
So, to answer your question:
b
is not null, it holds aNullable<bool>
with aHasValue
indicatingfalse
.GetType()
method on it, causes theNullable<bool>
struct to be boxed in order to access the underlying methodobject.GetType()
.(object)null
.((object)null).GetType()
, which throws theNullReferenceException
you encounter.If you're actually looking for a piece of code that can return the type of any variable, even a null
Nullable<T>
, use something like this:Which you can then call like this: