Consider the following code:
DateTime?开发者_Python百科 ndate = null;
Console.WriteLine(ndate.HasValue);
I would have expected a NullReferenceException, but HasValue will indeed return false. However, since ndate is null, how does the property invocation succeed, since there is no object to invoke the property HasValue on?
Technically, "ndate" is not null - it is a value type, with it's value specified as being null.
When you write DateTime?
, this is just shorthand for Nullable<DateTime>
, which is a struct. There is no way for this to technically be null, since it's not a reference type.
The Nullable<T>
is a struct, basically it can't hold a null
value.
Your assignment, is actually compiled into something that looks like this:
Nullable<DateTime> ndate = new Nullable<DateTime>();
Another example, the expression:
int? a = null;
Will generate the following IL:
.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0)
IL_0000: ldloca.s V_0
IL_0002: initobj valuetype [mscorlib]System.Nullable`1<int32>
A call to the initobj
operation, which initializes each field of the a value type at a specified address to a null reference or a 0 of the appropriate primitive type.
In conclusion, what's happening here is the default struct initialization.
I would have expected a NullReferenceException
There is no null reference being dereferenced, so "NullReferenceException" should not be expected. The nullable DateTime is not a null reference. It is a null value.
However, since ndate is null, how does the property invocation succeed, since there is no object to invoke the property HasValue on?
The question presupposes a false premise. There is an object. There's a nullable DateTime representing the null value of a nullable DateTime . That value is an object.
Consider your code:
DateTime? ndate = null;
Console.WriteLine(ndate.HasValue);
This is just a short way of writing something that is logically like:
DateTime ndate = default(DateTime);
bool ndateHasValue = false;
Console.WriteLine(ndateHasValue);
A nullable value type is simply a pleasant way to write code that means "please attach a Boolean to this thing that keeps track of whether it is logically null or not".
What really happens is that an actual (non-null) Nullable structure gets assigned to the variable, thus the variable is not null but it's Value is.
Synctactic sugar my friend ... the compiler turns that .HasValue call into code that won't throw an exception :-)
精彩评论