How to get all descriptions of enum values with reflection?
Solution 1
This generic static method works fine for getting a list of descriptions for each value of an enum type of T:
public static IEnumerable<string> GetDescriptions<T>()
{
var attributes = typeof(T).GetMembers()
.SelectMany(member => member.GetCustomAttributes(typeof (DescriptionAttribute), true).Cast<DescriptionAttribute>())
.ToList();
return attributes.Select(x => x.Description);
}
Solution 2
Here is a small reusable solution. This is an abstract class which will extract all the attributes of type K from type T.
abstract class AbstractAttributes<T, K>
{
protected List<K> Attributes = new List<K>();
public AbstractAttributes()
{
foreach (var member in typeof(T).GetMembers())
{
foreach (K attribute in member.GetCustomAttributes(typeof(K), true))
Attributes.Add(attribute);
}
}
}
Should we now want to extract only attributes of DescriptionAttribute
type, we would use the following class.
class DescriptionAttributes<T> : AbstractAttributes<T, DescriptionAttribute>
{
public List<string> Descriptions { get; set; }
public DescriptionAttributes()
{
Descriptions = Attributes.Select(x => x.Description).ToList();
}
}
This class will extract only attributes of DescriptionAttribute
type from the type T
. But to actually use this class in you context you will simply need to do the following.
new DescriptionAttributes<ContractorType>().Descriptions.ForEach(x => Console.WriteLine(x));
This line of code will write out all the descriptions you used as parameters in your attributes of type DescriptionAttribute
. Should you need to extract some other attributes, just create a new class that derives from the AbstractAttributes<T, K>
class and close its type K
with the appropriate attribute.
Solution 3
I created these extension methods
public static class EnumExtender
{
public static string GetDescription(this Enum enumValue)
{
string output = null;
Type type = enumValue.GetType();
FieldInfo fi = type.GetField(enumValue.ToString());
var attrs = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
if (attrs.Length > 0) output = attrs[0].Description;
return output;
}
public static IDictionary<T, string> GetEnumValuesWithDescription<T>(this Type type) where T : struct, IConvertible
{
if (!type.IsEnum)
{
throw new ArgumentException("T must be an enumerated type");
}
return type.GetEnumValues()
.OfType<T>()
.ToDictionary(
key => key,
val => (val as Enum).GetDescription()
);
}
}
Usage
var stuff = typeof(TestEnum).GetEnumValuesWithDescription<TestEnum>();
Will return a Dictionary<TestEnum, string>
with value as keys and descriptions as values. If you want just a list, you can change .ToDictionary
to
.Select(o => (o as Enum).GetDescription())
.ToList()
Solution 4
You need to find the DescriptionAttribute
on each field, if it exists and then retrieve the Description
attribute e.g.
return enumType.GetFields()
.Select(f => (DescriptionAttribute)f.GetCustomAttribute(typeof(DescriptionAttribute)))
.Where(a => a != null)
.Select(a => a.Description)
If you could have multiple descriptions on a field, you could do something like:
FieldInfo[] fields = enumType.GetFields();
foreach(FieldInfo field in fields)
{
var descriptionAttributes = field.GetCustomAttributes(false).OfType<DescriptionAttribute>();
foreach(var descAttr in descriptionAttributes)
{
yield return descAttr.Description;
}
}
which is more similar to your existing approach.
Harry89pl
C#, ASP.NET MVC/ few years ago webforms, Silverlight, WPF, Winforms, XNA 4.0, Ext.Net controls, jQuery, WCF, Windows Phone 7.5 Check my personal token: https://personaltokens.io/CHAR Check my blog in polish: http://charubiniak.pl
Updated on July 13, 2022Comments
-
Harry89pl almost 2 years
So I need to get a
List<string>
from myenum
Here is what I have done so far:
enum definition
[Flags] public enum ContractorType { [Description("Recipient")] RECIPIENT = 1, [Description("Deliver")] DELIVER = 2, [Description("Recipient / Deliver")] RECIPIENT_DELIVER = 4 }
HelperClass with method to do what I need:
public static class EnumUtils { public static IEnumerable<string> GetDescrptions(Type enumerator) { FieldInfo[] fi = enumerator.GetFields(); List<DescriptionAttribute> attributes = new List<DescriptionAttribute>(); foreach (var i in fi) { try { yield return attributes.Add(((DescriptionAttribute[])i.GetCustomAttributes( typeof(DescriptionAttribute), false))[0]); } catch { } } return new List<string>{"empty"}; } }
Now in the line where I
yield
values, I got aNullReferenceException
. Did I miss something? The syntax looks all right to me, but maybe I overlooked something?Edit: I'm using .net Framework 4.0 here.