Nullable Operators Not Just For Nullable Types
I read the C# spec for the new nullable operators last year. I forgot a couple of surprises until I reread the spec today.
First, the null coalescing operator (a ?? b), which returns the second operand if the first operand is null, also works on reference types, not just nullable value types. So, stringVariable ?? “default” returns “default” if stringVariable is null.
Second, a bool? is the C# equivalent of a ternary boolean, which can take three values—true, false or null. As such, it is treated differently from all other nullable variable types in order to mimic the behavior of database nulls. The “&” operator will still return false, if any operand is false, and the “|” operators will still return true, if any of the operands are true, even in presence of nulls. Normally, a null operand anywhere causes the entire expression to become null. Also, a bool? is accepted in any expression that normally takes a bool—if and while, for example.
Remaining Nullable Questions
In other nullable news, I was wondering what the impact of certain operations on Nullable<T> would be after the latest DCR(Design Change Request)?
The DCR causes the following invariant to fail:
new T?(value).GetType() returns typeof(T) rather than
typeof(T?). Even stranger, new T?().GetType()looks like it would return a null reference exception, because the default constructor produces a null value.
It also seems that Nullable<T> would produce a different result for GetHashCode() and ToString(), depending on whether it was boxed or not… In boxed form, we should get a null reference exception for a null value used in either of the two functions; in unboxed form from Beta 2, we would get zero for the hashcode value and an empty string for ToString().
Will “x is T?” always return true whenever “x is T”? It seems that since boxed objects can no longer internally store the type“Nullable<T>”, that “x is T?” should return whatever value “x is T” would return.
It also seems that “x as T?” operation should now be possible even though the “as” operator normally doesn’t work with value types; I hope the C# team doesn’t miss that.
Lastly, Is DBNullValue obsolete, now? What about the SQLInt32 and other System.Data SQLxxx type wrappers?
Interestingly, it is not possible to call any methods on Nullable<T> via reflection (except possibly by using the obscure technique of using TypedReferences.)