Click here to Skip to main content
Click here to Skip to main content

Terser Enum Programming with StrongEnum

By , 11 Jan 2009
Rate this:
Please Sign up or sign in to vote.

Introduction

Enums are great programming tools. They let you define groups of integral based constants that can be accessed elsewhere throughout your code in a strongly typed and symbolic fashion. The most obvious benefit of enums is their inherent catering to the rapid development model.

The Dilemma

The .NET library comes with a static class for enum management, System.Enum. Let's interrogate the method declarations provided by Enum:

  • object Enum.Parse(type, string)
  • object Enum.ToObject(type, object)
  • string Enum.GetName(type, object)
  • string[] Enum.GetName(type)
  • Array Enum.GetValues(type)
  • bool Enum.IsDefined(type, object)
  • Type Enum.GetUnderlyingType(type)
  • string Enum.Format(type, value, string)

Despite the wonderful functionality System.Enum provides us, it is not without its drawbacks. The first thing you should notice is that each method requires you to pass the type of enum that you wish to reference — not the enum itself, but the type of the enum. This means you have to encase the enum name within the typeof() system method. The second thing you should notice is that the Parse and ToObject methods return a type of object — this would require us to perform an explicit cast on the returned object to transform it into the designated enum object. This explicit cast resolves into a non-type-safe expression, as well as extra processing overhead.

Let's look at an example. Assume we have an enum called OrderStatus which defines four possible states: Open, Submitted, Shipped, and Invoiced.

public enum OrderStatus
{
    Open = 0,
    Submitted = 1,
    Shipped = 2,
    Invoiced = 3
}

Now, let's assume a customer wants to see all the orders that have been shipped. When the customer sends their request through, your server-side code parses the form collection if it is a POST request, or querystring if its a GET, and determines the order status filter chosen. Normally, if we want to put their choice in the form of a strongly typed enum object, we have to perform an explicit cast that looks like this:

protected void Page_Load(object sender, EventArgs e)
{
    NameValueCollection userData = Request.HttpMethod.ToUpper() == 
        "GET" ? Request.QueryString : Request.Form;
    OrderStatus orderStatus = 
        (OrderStatus)Enum.Parse(typeof(OrderStatus), userData["oStatus"]);
}

Now, this isn't too terrible looking, but imagine working with a multitude of enums within the same code block — it's going to get a little messy, and typing out typeof(MyEnum) many times over will become rather tedious and exhausting.

The Solution

The solution is incredibly simple — we will write a wrapper class that will make use of Generics to handle our enum needs in a type-safe manner. If you're not familiar with Generics, a quick explanation: they allow your classes and methods to perform operations on non-specific types, hence the term "generic". The most common use of Generics used in .NET are the Collection objects, such as List<> and Dictionary<>. After defining our Generics-supported class, all that is left to do is to implement the methods. Here is what our class should look like:

public static class StrongEnum<T>
{
    public static T Parse(string value)
    {
        return (T)Enum.Parse(typeof(T), value);
    }
    public static T Parse(string value, bool ignoreCase)
    {
        return (T)Enum.Parse(typeof(T), value, ignoreCase);
    }
    public static T ToObject(object value)
    {
        return (T)Enum.ToObject(typeof(T), value);
    }
    public static string GetName(object value)
    {
        return Enum.GetName(typeof(T), value);
    }
    public static string[] GetNames()
    {
        return Enum.GetNames(typeof(T));
    }
    public static Array GetValues()
    {
        return Enum.GetValues(typeof(T));
    }
    public static bool IsDefined(object value)
    {
        return Enum.IsDefined(typeof(T), value);
    }
    public static Type GetUnderlyingType()
    {
        return Enum.GetUnderlyingType(typeof(T));
    }
    public static string Format(object value, string format)
    {
        return Enum.Format(typeof(T), value, format);
    }
}

Now, we can write cleaner, strongly-typed enum operations:

protected void Page_Load(object sender, EventArgs e)
{
    NameValueCollection userData = Request.HttpMethod.ToUpper() == 
        "GET" ? Request.QueryString : Request.Form;
    OrderStatus orderStatus = 
        StrongEnum<OrderStatus>.Parse(userData["oStatus"]);
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

DevCubed
Software Developer DevCubed
United States United States
I am a programmer who enjoys working with many various languages and technologies, including but not limited to: C#, ASP.NET, T-SQL, XHTML, JavaScript, AJAX, NHibernate, Flash/Flex UI and ActionScript.

Comments and Discussions

 
GeneralEnum.Parse is too slow ! PinmemberGLLNS13-Jan-09 12:09 
GeneralRe: Enum.Parse is too slow ! PinmemberDevCubed13-Jan-09 14:11 
GeneralRe: Enum.Parse is too slow ! PinmemberGLLNS14-Jan-09 0:47 
GeneralRe: Enum.Parse is too slow ! PinmemberJohn Brett24-Feb-09 4:12 
GeneralI wouldn't do it this way Pinmemberjpbochi13-Jan-09 1:48 
GeneralRe: I wouldn't do it this way PinmemberDevCubed13-Jan-09 14:08 
GeneralReally good idea PinmemberBill Seddon12-Jan-09 23:47 
QuestionNice try, how about bitwise operations? Pinmembertvbusy11-Jan-09 4:28 
AnswerRe: Nice try, how about bitwise operations? PinmemberDevCubed11-Jan-09 8:13 
AnswerRe: Nice try, how about bitwise operations? Pinmemberpeterchen12-Jan-09 0:04 
GeneralRe: Nice try, how about bitwise operations? PinmemberPascal Ganaye12-Jan-09 3:36 
GeneralRe: Nice try, how about bitwise operations? Pinmemberpeterchen12-Jan-09 19:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140421.2 | Last Updated 11 Jan 2009
Article Copyright 2009 by DevCubed
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid