Enum ToString with user friendly strings
My enum consists of the following values:
private enum PublishStatusses{
NotCompleted,
Completed,
Error
};
I want to be able to output these values in a user friendly way though.
I don't need to be able to go from string to value again.
I use the Description
attribute from the System.ComponentModel namespace. Simply decorate the enum:
private enum PublishStatusValue
{
[Description("Not Completed")]
NotCompleted,
Completed,
Error
};
Then use this code to retrieve it:
public static string GetDescription<T>(this T enumerationValue)
where T : struct
{
Type type = enumerationValue.GetType();
if (!type.IsEnum)
{
throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
}
//Tries to find a DescriptionAttribute for a potential friendly name
//for the enum
MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
if (memberInfo != null && memberInfo.Length > 0)
{
object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0)
{
//Pull out the description value
return ((DescriptionAttribute)attrs[0]).Description;
}
}
//If we have no description attribute, just return the ToString of the enum
return enumerationValue.ToString();
}
I do this with extension methods:
public enum ErrorLevel
{
None,
Low,
High,
SoylentGreen
}
public static class ErrorLevelExtensions
{
public static string ToFriendlyString(this ErrorLevel me)
{
switch(me)
{
case ErrorLevel.None:
return "Everything is OK";
case ErrorLevel.Low:
return "SNAFU, if you know what I mean.";
case ErrorLevel.High:
return "Reaching TARFU levels";
case ErrorLevel.SoylentGreen:
return "ITS PEOPLE!!!!";
default:
return "Get your damn dirty hands off me you FILTHY APE!";
}
}
}
Maybe I'm missing something, but what's wrong with Enum.GetName?
public string GetName(PublishStatusses value)
{
return Enum.GetName(typeof(PublishStatusses), value)
}
edit: for user-friendly strings, you need to go through a .resource to get internationalisation/localisation done, and it would arguably be better to use a fixed key based on the enum key than a decorator attribute on the same.
I created a reverse extension method to convert the description back into an enum value:
public static T ToEnumValue<T>(this string enumerationDescription) where T : struct
{
var type = typeof(T);
if (!type.IsEnum)
throw new ArgumentException("ToEnumValue<T>(): Must be of enum type", "T");
foreach (object val in System.Enum.GetValues(type))
if (val.GetDescription<T>() == enumerationDescription)
return (T)val;
throw new ArgumentException("ToEnumValue<T>(): Invalid description for enum " + type.Name, "enumerationDescription");
}
The easiest solution here is to use a custom extension method (in .NET 3.5 at least - you can just convert it into a static helper method for earlier framework versions).
public static string ToCustomString(this PublishStatusses value)
{
switch(value)
{
// Return string depending on value.
}
return null;
}
I am assuming here that you want to return something other than the actual name of the enum value (which you can get by simply calling ToString).