I\'m having some hard time with trying to be generic with enums. I\'ve read that it\'s not that simple, and I can\'t seem to find a solution.
I\'m trying to create a
Modified your code slightly to pass in a Type to the description method and pass the parameter as a string value. This then gets converted back to the appropriate enum type and checked for the description.
public static KeyValuePair<string, List<KeyValueDataItem>> ConvertEnumWithDescription<T>() where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
throw new Exception("Type given T must be an Enum");
}
var enumType = typeof(T).ToString().Split('.').Last();
var type = typeof(T);
var itemsList = Enum.GetValues(typeof(T))
.Cast<T>()
.Select(x => new KeyValueDataItem
{
Key = Convert.ToInt32(x),
Value = GetEnumDescription<T>(Enum.GetName(typeof(T), x))
})
.ToList();
var res = new KeyValuePair<string, List<KeyValueDataItem>>(
enumType, itemsList);
return res;
}
public static string GetEnumDescription<T>(string enumValue)
{
var value = Enum.Parse(typeof(T), enumValue);
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
return attributes[0].Description;
return value.ToString();
}
Here, try this:
public static KeyValuePair<string, List<KeyValueDataItem>> ConvertEnumWithDescription<T>() where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
throw new Exception("Type given T must be an Enum");
}
var enumType = typeof(T).ToString().Split('.').Last();
var itemsList = Enum.GetValues(typeof(T))
.Cast<T>()
.Select(x => new KeyValueDataItem
{
Key = Convert.ToInt32(x),
Value = GetEnumDescription<T>(x.ToString())
})
.ToList();
var res = new KeyValuePair<string, List<KeyValueDataItem>>(
enumType, itemsList);
return res;
}
public static string GetEnumDescription<T>(string value)
{
Type type = typeof(T);
var name = Enum.GetNames(type).Where(f => f.Equals(value, StringComparison.CurrentCultureIgnoreCase)).Select(d => d).FirstOrDefault();
if (name == null)
{
return string.Empty;
}
var field = type.GetField(name);
var customAttribute = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
return customAttribute.Length > 0 ? ((DescriptionAttribute)customAttribute[0]).Description : name;
}
Based on: http://www.extensionmethod.net/csharp/enum/getenumdescription
I took the liberty of modifying some parts of the code, like changing the return types to more C# standard API return values.
You can watch it run here.
public static EnumDescription ConvertEnumWithDescription<T>() where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Type given T must be an Enum");
}
var enumType = typeof(T).Name;
var valueDescriptions = Enum.GetValues(typeof (T))
.Cast<Enum>()
.ToDictionary(Convert.ToInt32, GetEnumDescription);
return new EnumDescription
{
Type = enumType,
ValueDescriptions = valueDescriptions
};
}
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
return attributes[0].Description;
return value.ToString();
}
public class EnumDescription
{
public string Type { get; set; }
public IDictionary<int, string> ValueDescriptions { get; set; }
}