Friday, August 12, 2011

Trivialities about nullable types

Sometimes things in the world of software are not that hard. They are just poorly documented or documentation is hard to find. This surely applies for some use cases of nullable types. This post shows the use of nullable types in generic methods and how it’s easier than you might think.

An introduction to nullable types in C#

In order to understand the use of nullable types, it is imperative that you understand the difference between a value type and a reference type. For a complete description of these things have a look at chapter 4 of the C# 4.0 Language Specification (included with Visual Studio 2010). In short it comes down to this: value types directly contain their value, while reference types contain a reference to their value. Value types are always either a struct type or an enumeration type. Struct types include things like numeric types.

As value types always directly contain their value, they can not be null. However, in some cases, you might want to have a structure where you can identify if a value type is actually not defined. In lots of cases simply defining 0 as the undefined value for an int, for example. will not suffice. 0 might actually be a meaningful value for an int.

To provide a way of declaring a variable of a value type that can be null, C# introduces the question mark as a suffix to a value type:

int nonNullableInt = null;
int? nullableInt = null;

Line 1 doesn’t work, because null can not be assigned to a value type. Line 2 does work, because of the question mark behind the variable type.

Under the hood of nullable types

So what happens here? In fact the question mark in this context is syntactic sugar for Nullable<T>. So what happens is that nullableInt in the previous example is actually of type Nullable<int>. Because of this the variable now has a property Value, which contains the actual value if one is a available, and it gets HasValue of type bool, which indicates if a value is actually available.

Note that Nullable<T> is defined as a struct and is therefor a value type itself. Also note that T is limited to contain structs. Therefor it is not possible to apply Nullable<T> (or the question mark suffix for that matter) to a reference type.

Nullable types in generic methods

Now let’s get to the point. Let’s say you want to do some generic handling of input. So write a generic method with a signature like the following:

static string GetStringRepresentation<T>(T value)

You can simply call this with both non-nullable and nullable types. Because the compiler infers the type variable T I don’t even have to tell it what type value is explicitly. Let’s say we have the next program.

static void Main(string[] args)
{
int
nonNullableInt = 0;
int? nullableInt = null
;

Console
.WriteLine(GetStringRepresentation(nonNullableInt));
Console
.WriteLine(GetStringRepresentation(nullableInt));

Console.WriteLine("IsNullable(int): {0}", IsNullable(typeof(int
)));
Console.WriteLine("IsNullable(int?): {0}", IsNullable(typeof(int
?)));

Console.ReadLine();
}

The output of line 7 is actually an empty string. This is because the call to value is actually boxed because the call to ToString() is actually a call to object.ToString(). Because nullableInt is in effect null, it will return an empty string.

Obviously there are many reasons why that might not be correct for a nullable int, so let’s find a way to handle nullable types better in our generic method. The first thing to do is to detect if the passed in value is actually a nullable type. To do this we can use the type system:

static bool IsNullable(Type valueType)
{
return valueType.IsGenericType && valueType.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
}

What this method does is use the type passed in and checks if it’s a generic type. If it isn’t, it can’t be nullable. It needs that check because otherwise our second check on GetGenericTypeDefinition would throw an exception as it would not have a generic type definition to return. Our second check compares the returned generic type definition with the Nullable<> type. Another task we need to accomplish is to get a default value for a nullable type, or, more specifically, get a default value for it’s generic argument:

static object GetDefaultValue(Type nullableType)
{
Type
valueType = nullableType.GetGenericArguments()[0];
return Activator.CreateInstance(valueType);
}

This method takes a type and gets the first generic argument. This code assumes that you’ve already made sure this type is actually a nullable type. Normally you could use the default keyword to get a default value from a generic argument by writing default(T). As in this case we don’t have an actual type declaration, but a Type instance, we need a different approach to get a default value. If you’d check out the C# 4.0 reference you’d find out that the default keyword simply calls a default constructor on the type passed in and returns the result. To mimic that behavior, I simply call Activator.CreateInstance with the underlying type to get a default value. Now if we rewrite our GetStringRepresentation method to use the new methods above, we would end up with something like this:

static string GetStringRepresentation<T>(T value)
{
if (IsNullable(typeof(T)) && value == null
)
{
return GetDefaultValue(typeof
(T)).ToString();
}
return value.ToString();
}

Now, if we call this method with a int? it would return 0 instead of an empty string. For your convenience, I’ve uploaded a sample project here. I hope you’ve found this an interesting tour around nullable types. If you have any questions or comments, please use the comments form below. Thank you for reading.

Thursday, August 4, 2011

Bigger is not always better: Communication breakdown

Using Excel 2010 on Windows 7 to make an estimate for a new project, I ran into this problem that I think is both funny and a bit frustrating.

As we all know, Microsoft is a huge software company, with many developers and lots of QA people. Where they used to suffer from a reputation of poor quality, recent years have shown us Microsoft can make decent quality software with great features. Part of that ability comes from having lots of people working on projects. However, it can work against you as well, as Microsoft demonstrates in the following bug.

I’ve been a keen user of Excel for the past decade for a lot of different tasks. From simple estimations to long-list and complete data conversions, I’ve done it all with Excel. One of the long used features is the ability to block indent inside a cell. You know, these two buttons:

IndentButtons

I use this feature frequently, so I figured a keyboard shortcut would make me more productive. Fortunately for us Microsoft makes finding out shortcuts very easy. Just hover over the button:

ShortcutToolTip

Mm, something is not smelling right, but hey, maybe the Office developers did a great job on implementing these shortcut keys. So let’s just try it…

…No. That’s not what I wanted to happen. Instead of indenting the contents of my cell, it showed the Windows 7 process switching dialog thingy or whatever it’s called. You know, the preview of your open windows?

Turns out both the Windows 7 team and the Excel team are using the same shortcut here. Excel has been using it for a while (since before Excel 97!), but in Windows this was only introduced in Windows 7 for the first time! Didn’t anyone figure “hey, we wanted to use this keyboard shortcut in Windows 7, but it’s already used in Excel 2010 so let’s have a meeting to discuss this”? In fact, shouldn’t a company like Microsoft have some sort of registration on what keyboard shortcuts are used where?

Even worse, Microsoft knows about the problem right now and has it published on their website. Is it really that hard to get a patch out for Excel to assign a different shortcut key to this function?

There is a lesson to be learned here. If you work at a small software company (with say, under 20 developers), make sure you utilize this advantage of a small team and communicate! It can make sure that your next product / project will be great.