How many times have you stumbled over mess like this?

enum Days { Sat = 1, Sun, Mon, Tue, Wed, Thu, Fri };

 

private string DayToString(Days day)

{

    string str;

    switch (day) {

        case Days.Mon:

            str = "Mon";

            break;

        case Days.Tue:

            str = "Tue";

            break;

        case Days.Wed:

            str = "Wed";

            break;

        case Days.Thu:

            str = "Thu";

            break;

        case Days.Fri:

            str = "Fri";

            break;

        case Days.Sat:

            str = "Sat";

            break;

        case Days.Sun:

            str = "Sun";

            break;

        default:

            str = "Messday";

            break;

    }

    return str;

}


In C++ there was no easy way to cast enumerations to strings and vice versa thus many old dogs keep on using old tricks to do it. However in C# there are several easier ways to achieve the same result. First there is the obvious

Days day = Days.Mon;

dayAsString = day.ToString();


...and it actually works. Then there is a way to retreive string name by index using Enum.GetName function like this...

firstDayOfWeek = Enum.GetName(typeof(Days), 1);

dayAsString = Enum.GetName(typeof(Days),Days.Tue);


There also exists an easy way to cast string back to original enum value by using the Parse function.

Days today = (Days)Enum.Parse(typeof(Days), dayAsString);


Last but not least - for those of you who demand real sophistication - here are casts in both directions via descriptive attributes. The code is somehow sloppy since my objective is to show you how to do it - not do it for you. :)

using System;

using System.Collections.Generic;

using System.Text;

using System.Reflection;

using System.ComponentModel;

 

public class Warrior

{

    private class DescAttrFinder {

        private string descAttributeValue;

        public DescAttrFinder(string descAttributeValue)

        {

            this.descAttributeValue = descAttributeValue;

        }

 

        public bool FindPredicate(FieldInfo fi)

        {

            DescriptionAttribute[] descAttributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];

            string desc = (descAttributes.Length > 0) ? descAttributes[0].Description : null;

            return descAttributeValue.CompareTo(desc) == 0;

        }

    }

 

    public enum Rank

    {  

        [Description("Private")]

        Private = 1,

        [Description("Private First Class")]

        PrivateFirstClass,

        [Description("Specialist")]

        Specialist,

        [Description("Corporal")]

        Corporal,

        [Description("Seargant")]

        Seargant,

        [Description("Staff Sergeant")]

        StaffSergeant

    }

 

    public string GetRankDescription(Rank rank) {

        Type type = typeof(Rank);

        FieldInfo fieldInfo = type.GetField(rank.ToString());

        DescriptionAttribute[] descAttributes = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];

        return (descAttributes.Length > 0) ? descAttributes[0].Description : null;

    }

 

    public Rank GetRankFromDescription(string rank)

    {

        Type type = typeof(Rank);

        List <FieldInfo> fields= new List<FieldInfo>(type.GetFields());

        DescAttrFinder finder=new DescAttrFinder(rank);

        FieldInfo fi=fields.Find(finder.FindPredicate);

        return (Rank)fi.GetRawConstantValue();

    }

}

3 comment(s) :

Very very helpful information.
I started using Enums in C# the C++ way but then once you start reading about it you can do quite a lot.

E.g. This is also the first time I heard about the Parse.Method.

OK, all this will reduce my lines of code by quite a bit. I'm just wondering, is it also faster?

E.g. I used to have a dummy element in each enum called "_count", to get the number of elements.

Now I use the following:

public enum STUFF
{
first = 0,
second,
third
};

Enum.GetNames(typeof(STUFF)).Length;

What about the performance implications of this "elegant way"?

I'm using more than one enums and they're getting bigger and bigger...


Cheers!

Johannes

12:36 PM  

Thanks for the info. Incredibly useful to me tonight! Was going about it a much more complicated way!

9:16 PM  

Hi, thank you very much for help. I am going to test that in the near future. Cheers



Friends Phone  Cover

11:48 PM  

Newer Post Older Post Home

Blogger Syntax Highliter