I am trying to understand one thing in this code:
Nullable<Int32> x = 5;
Nullable<Int32> y = null;
Console.WriteLine("x: HasValue={0}, Value={1}", x.HasValue, x.Value);
Console.WriteLine("y: HasValue={0}, Value={1}", y.HasValue, y.GetValueOrDefault());
And Output is:
x: HasValue=True, Value=5
y: HasValue=False, Value=0
And the thing that I don't understand when you pass null
to y
, I believe it calls public static implicit operator Nullable<T>(T value)
but the definition of this method initializes a new struct passing value
which is assigned null
however constructor method doesn't check whether it is null or not so it can assign default(T)
to value
.
How come we can even assign null to struct here and it works fine?
Can you guys what I am missing out here? I don't understand how it just bypassed null
and returned default value.
Nullable code inner definition:
http://codepaste.net/gtce6d
believe it calls public static implicit operator Nullable(T value)
No it doesn't, because T
is Int32
in this case, and null
is not an Int32
. It just leaves the y
variable default, which means for a struct that all bytes are 0
. This results in a struct that has a HasValue
that returns false
.
You can't really pass null
to a struct, but the C# compiler is converting this for you to a default initalization.
The default is assigned in the constructor called by new Nullable<T>(value);
(Line 40)
My guess is that assigning null
to a nullable calls the default constructor. That is the only possible way for hasValue
to remain false
.
A Nullable<T>
is simply a structure which has a boolean field indicating whether it has a value, and a field which (if the first field is true) indicates what that value is. It isn't really possible to set any structure to null
, and a Nullable<T>
is no exception. Instead, the compiler translates a request to set a Nullable<T>
to null
as a request to set the "has value" field (reflected in property HasValue
) to false and set the "actual value" field (reflected in property Value
) to the default for its type.
Personally, I think pretending that a Nullable<T>
where HasValue
is false is null
is more confusing than helpful, but I am not Microsoft. I would think it would have been more helpful for each Nullable<T>
type to have a static property Nullable<T>.Null
(which would be equivalent to default(Nullable<T>)
, but the behavior of Nullable<T>
is sufficiently well-established I doubt it will ever change.