Wednesday, October 7, 2009

“Nullable object must have a value.” – could be a sign of something serious

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.
image
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.
image
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.
image
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.
image
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!
image
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”.
image
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:
image
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:
image
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