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();
}
}
Categories c#
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
Unknown said...
12:36 PM
Thanks for the info. Incredibly useful to me tonight! Was going about it a much more complicated way!
Unknown said...
9:16 PM
Hi, thank you very much for help. I am going to test that in the near future. Cheers
Friends Phone Cover
Kabir said...
11:48 PM