Visual Studio 2005 & .NET 2.0 introduced a bunch of new concepts to .NET development, probably the most well known being Generics. One of the possibly less well know & certainly less well understood was the introduction of nullable types, specifically nullable value types.
For the uninitiated, I’ve got a very brief intro below. Here’s a more in-depth article on Nullables.
Value types (int, long, float, double, etc.) are not able to be set to a null value, they’re set to their default value (for numeric value types this is 0). To make an int nullable, you append the type with a question mark, i.e. int? This means that you can now do this:
1: int? x;
2: //Some processing
3: if (x == null)
4: {
5: //Do something
6: }
Actually the nullable type wrapper gives you a more elegant way of checking for null with the HasValue property. All nullable types have this property & if the object is not null it will be true. The nullable type specification is actually a bit of syntactic sugar: int? is just a compiler shortcut for the real Nullable type of Nullable<int>.
Right, nifty, but so what? How do we use this? Well a simple use is when you need to pass through an optional value to a SQL Server stored proc. Previously you’d have to write an overloaded version of the method that didn’t have the optional parameter and just create a null sql parameter for the command. With a nullable int, you can just pass the parameter through as null.
However one usage that is possible less immediately apparent is in property loading. The Lazy loading pattern is frankly not used enough. For my 2 cents I recon for any property of an object that needs a seperate database hit to populate should be lazy loaded. For strings and reference type objects this is fine, you just check the underlying private field for null & load it in the get block of the property. Value types like ints are more difficult though, because their default value is in fact a value, and unless you know that it will never be a certain value (often -1) you’re left usually checking for some ridiculously small or large number that you hope will never be used. This is a mistake and can lead to major problems. The only other alternative is to either populate the value on the constructor or, worse, in the property getter. This isn’t great either because you’re often going to be making redundant database calls.
With nullable types, this is no longer a problem. What you do is create your property say,
1: int InvoiceCount
2: {
3: get { return _invoiceCount; }
4: set { _invoiceCount = value; }
5: }
Assuming _invoiceCount is being populated in the constructor.
But declare _invoiceCount as int? not int and you can remove that. By doing this you can change the property to:
1: int InvoiceCount
2: {
3: get {
4: if (!_invoiceCount.HasValue)
5: {
6: _invoiceCount = InvoiceCountMethod();
7: }
8: return _invoiceCount.GetValueOrDefault(0);
9: }
10: set { _invoiceCount = value; }
11: }
VoilĂ , a lazy loaded value type. There’s no need for casting because the GetValueOrDefault method returns the underlying value type of the nullable type. All that method does is remove the need to do this after calling the populating method:
1: if (!_invoiceCount.HasValue)
2: {
3: _invoiceCount = 0;
4: }
The 0 parameter on GetValueOrDefault is optional, if you don’t pass it a value it will return the default value for the type (in this case 0 anyway); The truly awesome fact of nullable types is that you can now make enums & structs nullable too. So you can now have a ‘none of the options’ value for an enum without having to create a lame ‘none’ enum option. You can now tell whether an enum variable has been given a value or not.
Obviously, using lazy loading introduces the whole new problem of ensuring thread safety, but I’m assuming that if you’re working in an environment where that is an issue you already know how to do that. Hey, at least it doesn’t mean you’ve now got two problems.
Hope this has helped someone out, I know this has made my life easier. Oh, and in case anyone was wondering, yes I’m back to regular posting again.
Here’s a few links about Nullable Types and working with nulls:
- The C# ?? null coalescing operator (and using it with LINQ)
It’s worth reading the comments on this one too, as you get this one from David:
It is also worth pointing out that because it evaluates the expression to the right, you can chain them up like such:
string item = DBValue ?? ConfigValue ?? “SomeOtherValue”;
I often use it like this to configure a properties value from a database, and if null from web.config, and if null from an inline value. All this can be done from a single line in an easy to read form.
- Nullable Types in .NET
- An interesting look at the performance of Nullable Types