At first glance, the
InvalidOperationException with the message
“Nullable object must have a value.” is probably the most senseless of all .NET exceptions. This is because the message is very misleading when one takes it by its face value. The most logical conclusion a reader can derive is that it’s something about failing to assign a non-
null value to a Nullable<T> object. Microsoft could have used a much better verbiage because what’s actually triggering the exception is an attempt to perform an action to the Nullable<T> object which value happens to be
null. In other words, it’s about an invalid action, not value.
Figure 1 – A message that can leave you dumbfounded
Unfortunately, the capability of Visual Studio in detecting null
nullable is limited only to uninitialized fields. If the
nullable object is a property, then all you can do is sit and wait for the bomb to go off. In Figure 2, the properties SampleClass.NullableBool and Program.NullableBool are never checked by Visual Studio whereas _nullableBool cannot escape the scrutiny.
Figure 2 – Visual Studio can help detect only uninitialized nullable fields
Figure 3 shows the most common mistakes that trigger the exception. The first case is when the Value property is called to extract the encapsulated native type. The second case is quite common among new programmers where instead of calling Value, a cast is performed on the
nullable object.
Figure 3 – Be on the lookout for lines similar to these
Bear in mind though that calling ToString() on a null nullable is perfectly legal as long as it’s initialized. It simply yields a blank which is what exactly we want in the UI.
Figure 4 – It’s safe to call ToString as long as the nullable is initialized
There Could Me Something More
When you’re done cursing Microsoft, do yourself a favor and go back to your codes. The message could be a sign of a more serious type of bug lurking somewhere. This is because it’s possible that nullables are used in boolean conditions without the benefit of a prior
nullability check. If this is the case and the coder does not call the Value property, the compiler does not complain at all. It simply evaluates the condition as false!
Figure 5 – A null nullable is always evaluated as false
In the business rules of your application, it might be that a
null is equivalent to a false and in this case, you could care less about codes similar to Figure 5. However, the fact that 3-value logic is already allowed to permeate in the application also means that
null deserves a separate treatment altogether. A
null could mean “I don’t know”, “not yet”, or “maybe”.
Figure 6 – This block can wreak havoc in your application.
Defensive Coding
Nullable<T>.HasValue can be used to check if the value is null. You usually use this whenever a null value is treated differently as illustrated in the snippet below:
Figure 7 – Using HasValue prevents exception and aids in the 3-value logic evaluation
In the rare cases where a
null means false or any valid value of a type, one can use the coalesce C# operator ?? as shown here:
Figure 8 – The coalesced operator is handy when null value can be interpreted in some other way
In the next release of .NET, I hope we could get a much more meaningful message, something like “Attempting to perform action to a Nullable<T> is not allowed when its value is null.” Whatcha think?
No comments:
Post a Comment