Reputation: 9095
I was looking at the following code for the .NET Nullable<T>
class: http://referencesource.microsoft.com/#mscorlib/system/nullable.cs,ffebe438fd9cbf0e
And I was wondering, what would be its behavior for the following use:
int? x = null;
Obviously, x.hasValue()
returns false
, however I see that in the constructor, hasValue
property is always set to true
.
So what am I missing?
Upvotes: 3
Views: 1078
Reputation: 14896
Nullable types are treated in a special way by C#, not like regular struct
s.
It's not possible to assign a null
to a regular struct
variable, but it's possible to assign it to a Nullable<T>
variable. Why? It's described in C# language specification, section 6.1.5
6.1.5 Null literal conversions
An implicit conversion exists from the null literal to any nullable type. This conversion produces the null value (§4.1.10) of the given nullable type.
The compiler implements this conversion as a call to the default parameterless constructor of Nullable<T>
. Every struct
has an implicit parameterless constructor, which initializes all fields to their default values. The default value of bool
is false
.
Upvotes: 1
Reputation: 391336
"the constructor", yes, the constructor that is explicitly written for Nullable<T>
, however all structs have one additional constructor, a parameterless default constructor that you're not allowed to implement. This will always be present.
So you can think of the code from your question as similar to this:
int? x = new Nullable<int>();
In fact, if we compile your code and my code and look at the generated IL:
Your code:
IL_0001: ldloca.s 00 // a
IL_0003: initobj System.Nullable<System.Int32>
My code:
IL_0001: ldloca.s 00 // a
IL_0003: initobj System.Nullable<System.Int32>
So they're completely identical.
The default constructor for a struct initializes all fields to byte-wise zeroes, which equates to false for bool fields, 0 for number fields, null
for reference type fields, etc.
Upvotes: 7
Reputation: 156978
From the documentation on MSDN:
Structs cannot contain explicit parameterless constructors. Struct members are automatically initialized to their default values.
That means there is always a 'default parameterless constructor'. You don't see it, but it is always there. If you pass in a value for T
(which isn't nullable), the constructor can assume it has a value.
Try for example this one:
Nullable<int> c = new Nullable<int>();
Console.WriteLine(c.HasValue); // false
c = new Nullable<int>(1);
Console.WriteLine(c.HasValue); // true
Upvotes: 1