May 25

.Net and nullable value types – part II

Posted in .NET Basics C#      Comments Off on .Net and nullable value types – part II

In the previous post, I’ve introduced the concept of nullable value types. As I’ve said back then, C# allows us to use a simplified syntax for working with nullable value types:

Int32? aux = 10;
Int32? aux2 = null;
Console.WriteLine("aux, has value: {0}, value: {1}", aux.HasValue, aux.Value);
Console.WriteLine("aux2, has value: {0}, value: {1}", aux2.HasValue, aux2.GetValueOrDefault());

This code is equivalent to the one presented in the previous post. Whenever the compiler finds the XXX? type declaration, it will always convert it into a Nullable<XXX> declaration. But there’s more. I’m not sure if you’ve noticed it, but I’ve initialized the aux2 variable with null. But how can this be if Nullable<T> is a struct? This is only possible because there’s special support for the Nullable<T> type.

Since Nullable<T> instances should behave like Ts, then it’s also possible to apply other “known” operators to these instances:

Int32? aux = 10;
Int32? aux2 = null;
aux2++;//still null

Isn’t this fantastic? You can also use binary operators with Nullable<T> instances:

Int32? aux = 10;
Int32? aux2 = 20;
var aux3 = aux + aux2;

When using binary operators, the final result will always be null if one of the instances hasn’t got a “valid value” (ie, if the HasValue property returns false). Finally, you can also check for equality (== and !=) and compare instances (<, >, <=, >=). There is, however, a catch: the code generated for performing these operations is longer than the one you get when you use Ts directly. One final note regarding operators: since T (from Nullable) can be replaced by any struct, then you can create a custom struct and make it “nullable”. Notice that if your custom struct introduces custom operators, then they will be called when you’re manipulating nullable instances of those types! This is simply great!

Finally, and since I’m presenting some C# specific simplifications, I couldn’t end this post without mentioning the null coalescing operator (??). This operator takes two operands. If the one on the left isn’t null, that operand’s value is return. If it is, then the value of right operand is returned. This operator can simplify the code needed for initializing variables:

Int32? aux = null;
//same as aux.HasValue ? aux : 20
//or aux.GetValueOrDefault(20)
Int32? aux2 = aux ?? 20;

Before going on, it’s important to understand that the null coalescing operator can also be applied to  reference types. Some say that this operator wasn’t really needed because you could always use the ? : operator. Well, that’s probably true, but there’s one scenario where the null coalescing operator introduces a clear advantage: readability in composition scenarios. Here’s an example:

Int32? aux2 = aux ?? aux2 ?? aux3;

I’d say that reading this line is easy and simple…And I guess that’s it for now. Stay tuned for more!