Tuesday, October 6, 2009

Adventures while building a Silverlight Enterprise application part #24

Recently I was working out some details to include in our applications framework, when I encountered some old school enum stuff, that I'd like to share with you. It's all about using char implicitly as sort of the underlying type of an enum and why you might want that.

The story
As I was working on one of the modules we need in our application I had to figure out a way to store a persons gender. As it turns out, we don't have any data in the database specifying a list of genders. As this is all about what gender is on someones passport, we only needed two values (obviously 'male' and 'female') and we decided to only store the first character of these values in the database. The reason we didn't want to have a Gender table in our database was because of clarity. We have introduced this rule, saying that all primary keys should be of the SQL type uniqueidentifier (.NET type Guid) and having a foreign key for gender would result in storing a Guid for each and every gender in the database, which would not only be overkill, but it would also make things complicated.

So on the database side we had a char(1) column. But that's not what you want throughout your .NET code. Having an enum for this scenario is the obvious choice and that is what I went for. Luckily Silverlight is very well equipped for data binding enum types. There was one possible issue here. .NET enums only support int types as their underlying type...

...or do they? Obviously specifying something like enum Gender : char would not compile, but what about this:

public enum Gender
{
Female = 'f',
Male = 'm'
}


This is actually valid. But what happens then? Is char now the underlying type for this enum? Let's find out. I ran the following code to find out:

MessageBox.Show(string.Format("Enum underlying type: {0}", Enum.GetUnderlyingType(typeof(Gender)).Name));

As it turns out the underlying type is Int32. Hmmm, would this actually work? What value is it actually storing?
I expanded my code to the following:

MessageBox.Show(string.Format("Enum underlying type: {0}\r\n" +
"Enum value as int: {1}\r\n" +
"Enum value as char: {2}",
Enum.GetUnderlyingType(typeof(Gender)).Name,
((int)_person.Gender).ToString(),
((char)_person.Gender).ToString()
));

Now it would show me the int value and the char value casts for the selected gender value. In this case _person.Gender was Gender.Male. The actual int that was stored was 109, which is the byte value of the 'm' char. The ToString method on the char cast returned the 'm' char.

That's just great. Now I can store my Gender enum values by casting them to char at some point. But how about loading it pack into the Gender enum? As it turns out, you are allowed to cast this both ways, so something like this works:

_person.Gender = (Gender)genderCharTextBox.Text[0];

Duality rocks, man! So now we can store enum types without an underlying model with ease. Simple but powerful stuff, which I hope helps you out.

I've uploaded a simple project, which I used to test all this, here.

No comments:

Post a Comment