Thursday, April 22, 2010

C# Enum with char valued items

Hello again!
I'm finally back, and still I haven't fulfilled my promise of writing about .NET 4 and VS2010, but I'm working on it, and maybe I'll talk about VS2010 testing features as well and also Entity Framework 4 new hot stuff!

Focusing on the subject, what am I going to write about the Enum type?

- Can we assign an Enum item to anything that's not of the int type?
- Why would I even bother thinking about this?
- How can I handle converting something to Enum and back to something again?

First of all, YES, we can assign an Enum to something else, a char!
And how?
Just like you're thinking about it, yes:

public Enum myEnum {
value1 = 'a',
value2 = 'b'
}

And why would I think about this?
Have you ever had to write some DAL code or mapping and existing database to and ORM, say Entity Framework, and you had fields which contained, for some particular reason, a list of controlled chars, which aren't related to any other table, like a field called State which had the possible values, 'R' for Ready, 'P' for Pending and 'C' for cancelled, and you want to have some nice and type-safe way of manipulating this field on code and at the same time a generic way, which can be used everywhere, well, you can do it using those chars on an Enum type:

public Enum State {
Ready = 'R',
Pending = 'P',
Cancelled = 'C'
}

And how can I handle this? I'll sure try to do a State.ToString() and it will return me a number, why??
Because, actually, you can't have an Enum item with an associated char, but .NET lets you do this, and internally it converts your char to it's equivalent int representation (ASCII).
So, now you're thinking, so now what? How can I get my char??
Simple enough, just cast the Enum item to a char first, and then you get it's char representation:

string type = ((char)StateEnum).ToString();

This way you can extract the char from the int, and get your value!

This is for persisting your data to your datasource (convert the Enum item to the value that your datasource is expecting, the char).

But now you need to convert your char to the corresponding Enum item, when you get your char field from your datasource, right?
How can this be done?
Well I've coded a method to do that, with generics, lets see:

Code at Pastebin
public static T ToEnum< T >(string @string)
  {
   if (string.IsNullOrEmpty(@string))
   {
    throw new ArgumentException("Argument null or empty");
   }
   if (@string.Length > 1)
   {
    throw new ArgumentException("Argument length greater than one");
   }
   return (T)Enum.ToObject(typeof(T), @string[0]);
  }

So what you do here is accept a string (could be a char, it's just to make it simplier, since many ORMs map a char on the database to string, not chat), and then you check your parameters, ir they're not null, and if the length of the string is one (which matches a char), and then, you use the ToObject method from the Enum type, that accepts the return type you want to get, and the corresponding Enum item value (int or char) to convert to.

And that's it, you can use chars with an Enum object, isn't this awesome?
When i got around this, I just thought about the lots of times that I needed it...

Hope this helps you as much as it helped me.

Be back soon!