Mugen
Mugen

Reputation: 9095

Nullable initialized to null - understanding the source code

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

Answers (3)

Jakub Lortz
Jakub Lortz

Reputation: 14896

Nullable types are treated in a special way by C#, not like regular structs.

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

Lasse V. Karlsen
Lasse V. Karlsen

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

Patrick Hofman
Patrick Hofman

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

Related Questions