I just found this one while writing up some code for the XMPCR library.
Believe it or not, this is valid code:
private DateTime? turnOnDate;
This is apparently shorthand for using the new Nullable generic type so you can assign a database-style null value to a struct — in other words null means no value rather than no object.
Using Nullable<T> is also a bit easier under beta 1 than it was under the CTP because it provides transparent creation/usage of Nullable.
// old style - going from memory Nullable<T> turnOnDate = new Nullable<T>( null ); // Beta 1 style DateTime? turnOnDate = null;
Much better in my opinion.
Even better is that using it is pretty transparent. While this code is pretty obvious what it does, it is an over simplification of what i’m using elsewhere.
DateTime? foo = DateTime.Now; TimeSpan? blah = DateTime.Now - ( foo + TimeSpan.FromMilliseconds( 500 ) );
Notice that I can use the operator overloads defined on the DateTime structure, in this case I am using two overloads. The + overload which returns a new DateTime instance that is the value of the timespan added to the DateTime. The second one, is the – overload which returns a TimeSpan instance which represents the amount of time between the two DateTime instances. Notice that the overall return value is a TimeSpan? (a Nullable<TimeSpan>), yet only one of the values in the equation on the right is Nullable, the foo variable. I’m not exactly sure what is going on there.
Running the above code under the debugger it works as expected. What is more interesting though is that if I change the code to:
DateTime? foo = null; TimeSpan? blah = DateTime.Now - ( foo + TimeSpan.FromMilliseconds( 500 ) );
When I run this under the debugger blah is equal to null.
How does it all work? The secret lies in
T Nullable<T>.GetValueOrDefault(); thanks to generics that method can return a valid default value if the instance is set to null. As an aside, that method is already marked with the obsolete attribute saying that you should use
T Nullable.GetValueOrDefault<T>(T value);. I assume by the time the next beta comes out the compiler will be emitting the correct method to call.
It is important to note that Nullable is only useful when you use it with value types, because reference types can already be null there isn’t any advantage in using it and the
GetValueOrDefault method would return an unusable value which wouldn’t help if you are using Nullable like I am in the last code snippet above; you would get a NullReferenceException while trying to perform the first addition.
End of ramble