Reputation: 361
I'm looking to create a function that converts an Enum to a dictionary list. The Enum names will also be converted into a more human readable form. I'd like to just call the function, provide the enum type, and get the dictionary back. I believe I'm almost there I just can't seem to figure out how to cast the enum to the correct type. (Getting an error on the 'returnList.Add' line). Right now I'm just using var for the type, however I do know the type, as it's passed in.
internal static Dictionary<int,string> GetEnumList(Type e)
{
List<string> exclusionList =
new List<string> {"exclude"};
Dictionary<int,string> returnList = new Dictionary<int, string>();
foreach (var en in Enum.GetValues(e))
{
// split if necessary
string[] textArray = en.ToString().Split('_');
for (int i=0; i< textArray.Length; i++)
{
// if not in the exclusion list
if (!exclusionList
.Any(x => x.Equals(textArray[i],
StringComparison.OrdinalIgnoreCase)))
{
textArray[i] = Thread.CurrentThread.CurrentCulture.TextInfo
.ToTitleCase(textArray[i].ToLower());
}
}
returnList.Add((int)en, String.Join(" ", textArray));
}
return returnList;
}
Upvotes: 2
Views: 6745
Reputation: 41
Some time is the better way to use enum with description, and get Dictonary(EnumValue, EnumValueDescription) via generic method. I use it when I need view filter in dropdown. You can use it for any enums in yours code.
For example:
public static class EnumExtensions
{
public static string GetDescription(this Enum value)
{
Type type = value.GetType();
string name = Enum.GetName(type, value);
if (name != null)
{
FieldInfo field = type.GetField(name);
if (field != null)
{
var attr = Attribute.GetCustomAttribute(field, typeof (DescriptionAttribute)) as DescriptionAttribute;
if (attr != null)
{
return attr.Description;
}
}
}
return value.ToString();
}
public static Dictionary<T, string> EnumToDictionary<T>()
{
var enumType = typeof(T);
if (!enumType.IsEnum)
throw new ArgumentException("T must be of type System.Enum");
return Enum.GetValues(enumType)
.Cast<T>()
.ToDictionary(k => k, v => (v as Enum).GetDescription());
}
}
And call looks like this:
public static class SomeFilters
{
public static Dictionary<SomeUserFilter, string> UserFilters = EnumExtensions.EnumToDictionary<SomeUserFilter>();
}
For enum:
public enum SomeUserFilter
{
[Description("Active")]
Active = 0,
[Description("Passive")]
Passive = 1,
[Description("Active & Passive")]
All = 2
}
Upvotes: 4
Reputation: 705
Please note that types defined using enum, in C#, can have a variety of underlying types (byte, sbyte, short, ushort, int, uint, long, ulong) as the doc says: enum. This means that not all enum values can be safely casted to int and get away without an exception being thrown.
For instance if you wish you generalize you can safely cast all enum values to float (although odd, it covers any enum underlying type as the Implicit Numeric Conversions Table tells). Or you can request a specific underlying type via generics.
Neither solution is perfect although both get the job done safely with adequate parameter validation. Generalization to float values solution:
static public IDictionary<float, string> GetEnumList(Type enumType)
{
if (enumType != null)
if (enumType.IsEnum)
{
IDictionary<float, string> enumList = new Dictionary<float, string>();
foreach (object enumValue in Enum.GetValues(enumType))
enumList.Add(Convert.ToSingle(enumValue), Convert.ToString(enumValue));
return enumList;
}
else
throw new ArgumentException("The provided type is not an enumeration.");
else
throw new ArgumentNullException("enumType");
}
Generic parameter solution:
static public IDictionary<EnumUnderlyingType, string> GetEnumList<EnumUnderlyingType>(Type enumType)
{
if (enumType != null)
if (enumType.IsEnum && typeof(EnumUnderlyingType) == Enum.GetUnderlyingType(enumType))
{
IDictionary<EnumUnderlyingType, string> enumList = new Dictionary<EnumUnderlyingType, string>();
foreach (object enumValue in Enum.GetValues(enumType))
enumList.Add((EnumUnderlyingType)enumValue, enumValue.ToString());
return enumList;
}
else
throw new ArgumentException("The provided type is either not an enumeration or the underlying type is not the same with the provided generic parameter.");
else
throw new ArgumentNullException("enumType");
}
Or you can use one of these in combination with lazyberezovsky's solution to avoid null check. Or better the provided solutions by using implicit conversions (say you have an enum with underlying type char, you can safely convert a char to an int meaning that the method, if requrested to return a dictionary of int keys being the enum values with a provided enum who's underlying type is char, should work without a problem since there's no problem in storing a char on a int).
Upvotes: 1
Reputation: 236208
You can use generic method, which will create dictionary with enum values and names:
public static Dictionary<int, string> GetEnumList<T>()
{
Type enumType = typeof(T);
if (!enumType.IsEnum)
throw new Exception("Type parameter should be of enum type");
return Enum.GetValues(enumType).Cast<int>()
.ToDictionary(v => v, v => Enum.GetName(enumType, v));
}
Feel free to modify default enum name as you need. Usage:
var daysDictionary = Extensions.GetEnumList<DayOfWeek>();
string monday = daysDictionary[1];
Upvotes: 6