599

I would like to know if it is possible to get attributes of the enum values and not of the enum itself? For example, suppose I have the following enum:

using System.ComponentModel; // for DescriptionAttribute
enum FunkyAttributesEnum
{
 [Description("Name With Spaces1")]
 NameWithoutSpaces1, 
 [Description("Name With Spaces2")]
 NameWithoutSpaces2
}

What I want is given the enum type, produce 2-tuples of enum string value and its description.

Value was easy:

Array values = System.Enum.GetValues(typeof(FunkyAttributesEnum));
foreach (int value in values)
 Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), value);

But how do I get description attribute's value, to populate Tuple.Desc? I can think of how to do it if the Attribute belongs to the enum itself, but I am at a loss as to how to get it from the value of the enum.

Eliahu Aaron
4,6325 gold badges32 silver badges43 bronze badges
asked Nov 25, 2009 at 19:23
5

29 Answers 29

551

This should do what you need.

try {
 var enumType = typeof(FunkyAttributesEnum);
 var memberInfos = enumType
 .GetMember(FunkyAttributesEnum.NameWithoutSpaces1.ToString());
 var enumValueMemberInfo = memberInfos
 .FirstOrDefault(m => m.DeclaringType == enumType);
 var valueAttributes = enumValueMemberInfo
 .GetCustomAttributes(typeof(DescriptionAttribute), false);
 var description = ((DescriptionAttribute)valueAttributes[0])
 .Description;
} catch {
 return FunkyAttributesEnum.NameWithoutSpaces1.ToString()
}
Inspi
6091 gold badge7 silver badges22 bronze badges
answered Nov 25, 2009 at 19:28

4 Comments

Optionally use type.GetFields(BindingFlags.Public | BindingFlags.Static) to get all the memInfos at once.
I had to go typeof(FunkyAttributesEnum), but other than that it worked well. Thanks.
@AlexK I don't see Enum class has a NameWithoutSpaces1 property. Where does the FunkyAttributesEnum.NameWithoutSpaces1 come from?
@Don, it's the enum member name from the OP's question.
390

This piece of code should give you a nice little extension method on any enum that lets you retrieve a generic attribute. I believe it's different to the lambda function above because it's simpler to use and slightly - you only need to pass in the generic type.

public static class EnumHelper
{
 /// <summary>
 /// Gets an attribute on an enum field value
 /// </summary>
 /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
 /// <param name="enumVal">The enum value</param>
 /// <returns>The attribute of type T that exists on the enum value</returns>
 /// <example><![CDATA[string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;]]></example>
 public static T GetAttributeOfType<T>(this Enum enumVal) where T:System.Attribute
 {
 var type = enumVal.GetType();
 var memInfo = type.GetMember(enumVal.ToString());
 var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
 return (attributes.Length > 0) ? (T)attributes[0] : null;
 }
}

Usage would then be:

string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;
answered Feb 14, 2012 at 11:52

8 Comments

I like this one more than Scott's, because the usage is cleaner here (less typing), so +1 :)
If no attribute exists, wouldn't this throw a IndexOutOfRangeException?
better use type.GetMember(Enum.GetName(type, enumVal)) for the memInfo as enumVal.ToString() may not be reliable for different locales.
What is the point of calling GetCustomAttributes() then get first element instead of calling GetCustomAttribute() ?
@tigrou this extension was added quite recently to the .NET framework; the solution (which is from 2009) might need an update.
|
100

This is a generic implementation using a lambda for the selection

public static Expected GetAttributeValue<T, Expected>(this Enum enumeration, Func<T, Expected> expression)
 where T : Attribute
{
 T attribute =
 enumeration
 .GetType()
 .GetMember(enumeration.ToString())
 .Where(member => member.MemberType == MemberTypes.Field)
 .FirstOrDefault()
 .GetCustomAttributes(typeof(T), false)
 .Cast<T>()
 .SingleOrDefault();
 if (attribute == null)
 return default(Expected);
 return expression(attribute);
}

Call it like this:

string description = targetLevel.GetAttributeValue<DescriptionAttribute, string>(x => x.Description);
M Reza
19.9k15 gold badges72 silver badges78 bronze badges
answered Feb 2, 2011 at 17:30

3 Comments

This is great. We just have to be carefull if the given enumeration value is a combination (allowed by FlagsAttribute). In this case, enumeration.GetType().GetMember(enumeration.ToString())[0] will fail.
The shortest you could write: value.GetType().GetField(value.ToString()).GetCustomAttributes(false).OfType<T>‌​().SingleOrDefault(), but have to admit your explicit way is better.
I also add public static String GetDescription(this Enum enumeration) { return enumeration.GetAttributeValue<DescriptionAttribute, String>(x => x.Description); } that way its just targetLevel.GetDescription();
91

I've merged a couple of the answers here to create a little more extensible solution. I'm providing it just in case it's helpful to anyone else in the future. Original posting here.

using System;
using System.ComponentModel;
public static class EnumExtensions {
 // This extension method is broken out so you can use a similar pattern with 
 // other MetaData elements in the future. This is your base method for each.
 public static T GetAttribute<T>(this Enum value) where T : Attribute {
 var type = value.GetType();
 var memberInfo = type.GetMember(value.ToString());
 var attributes = memberInfo[0].GetCustomAttributes(typeof(T), false);
 return attributes.Length > 0 
 ? (T)attributes[0]
 : null;
 }
 // This method creates a specific call to the above method, requesting the
 // Description MetaData attribute.
 public static string ToName(this Enum value) {
 var attribute = value.GetAttribute<DescriptionAttribute>();
 return attribute == null ? value.ToString() : attribute.Description;
 }
}

This solution creates a pair of extension methods on Enum. The first allows you to use reflection to retrieve any attribute associated with your value. The second specifically calls retrieves the DescriptionAttribute and returns it's Description value.

As an example, consider using the DescriptionAttribute attribute from System.ComponentModel

using System.ComponentModel;
public enum Days {
 [Description("Sunday")]
 Sun,
 [Description("Monday")]
 Mon,
 [Description("Tuesday")]
 Tue,
 [Description("Wednesday")]
 Wed,
 [Description("Thursday")]
 Thu,
 [Description("Friday")]
 Fri,
 [Description("Saturday")]
 Sat
}

To use the above extension method, you would now simply call the following:

Console.WriteLine(Days.Mon.ToName());

or

var day = Days.Mon;
Console.WriteLine(day.ToName());
answered Oct 27, 2013 at 18:07

2 Comments

On the last line, you mean "attribute.Description" ? return attribute == null ? value.ToString() : attribute.Description;
Best and simplest answer.
41

In addition to AdamCrawford response, I've further created a more specialized extension methods that feed of it to get the description.

public static string GetAttributeDescription(this Enum enumValue)
{
 var attribute = enumValue.GetAttributeOfType<DescriptionAttribute>();
 return attribute == null ? String.Empty : attribute.Description;
} 

hence, to get the description, you could either use the original extension method as

string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description

or you could simply call the the extension method here as:

string desc = myEnumVariable.GetAttributeDescription();

Which should hopefully make your code a bit more readable.

answered Jun 18, 2013 at 15:06

Comments

26

Fluent one liner...

Here I'm using the DisplayAttribute which contains both the Name and Description properties.

public static DisplayAttribute GetDisplayAttributesFrom(this Enum enumValue, Type enumType)
{
 return enumType.GetMember(enumValue.ToString())
 .First()
 .GetCustomAttribute<DisplayAttribute>();
}

Example

public enum ModesOfTransport
{
 [Display(Name = "Driving", Description = "Driving a car")] Land,
 [Display(Name = "Flying", Description = "Flying on a plane")] Air,
 [Display(Name = "Sea cruise", Description = "Cruising on a dinghy")] Sea
}
void Main()
{
 ModesOfTransport TransportMode = ModesOfTransport.Sea;
 DisplayAttribute metadata = TransportMode.GetDisplayAttributesFrom(typeof(ModesOfTransport));
 Console.WriteLine("Name: {0} \nDescription: {1}", metadata.Name, metadata.Description);
}

Output

Name: Sea cruise 
Description: Cruising on a dinghy
answered Aug 3, 2014 at 21:32

3 Comments

I use this too, it's the most clean of all the answers! +1
This seems to be quite useful! Thnx
You can use enumValue.GetType() to eliminate the enumType argument.
9

If your enum contains a value like Equals you might bump into a few bugs using some extensions in a lot of answers here. This is because it is normally assumed that typeof(YourEnum).GetMember(YourEnum.Value) would return only one value, which is the MemberInfo of your enum. Here's a slightly safer version Adam Crawford's answer.

public static class AttributeExtensions
{
 #region Methods
 public static T GetAttribute<T>(this Enum enumValue) where T : Attribute
 {
 var type = enumValue.GetType();
 var memberInfo = type.GetMember(enumValue.ToString());
 var member = memberInfo.FirstOrDefault(m => m.DeclaringType == type);
 var attribute = Attribute.GetCustomAttribute(member, typeof(T), false);
 return attribute is T ? (T)attribute : null;
 }
 #endregion
}

Edit (3rd May 2023)

GetField works well in this case. typeof(YourEnum).GetField(YourEnum.Value) should produce the desired result.

public static T GetAttribute<T>(this Enum value) where T : Attribute
{
 Type type = value.GetType();
 FieldInfo field = type.GetField(value.ToString());
 Attribute attr = Attribute.GetCustomAttribute(field, typeof(T), false);
 return (T)attr;
}

Thanks to mjwills for pointing this out.

answered May 12, 2019 at 19:35

2 Comments

Could GetField be used rather than GetMember?
Yes, it appears you can actually. I will update the answer accordingly, good catch!
7

Here is code to get information from a Display attribute. It uses a generic method to retrieve the attribute. If the attribute is not found it converts the enum value to a string with pascal/camel case converted to title case (code obtained here)

public static class EnumHelper
{
 // Get the Name value of the Display attribute if the 
 // enum has one, otherwise use the value converted to title case. 
 public static string GetDisplayName<TEnum>(this TEnum value)
 where TEnum : struct, IConvertible
 {
 var attr = value.GetAttributeOfType<TEnum, DisplayAttribute>();
 return attr == null ? value.ToString().ToSpacedTitleCase() : attr.Name;
 }
 // Get the ShortName value of the Display attribute if the 
 // enum has one, otherwise use the value converted to title case. 
 public static string GetDisplayShortName<TEnum>(this TEnum value)
 where TEnum : struct, IConvertible
 {
 var attr = value.GetAttributeOfType<TEnum, DisplayAttribute>();
 return attr == null ? value.ToString().ToSpacedTitleCase() : attr.ShortName;
 }
 /// <summary>
 /// Gets an attribute on an enum field value
 /// </summary>
 /// <typeparam name="TEnum">The enum type</typeparam>
 /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
 /// <param name="value">The enum value</param>
 /// <returns>The attribute of type T that exists on the enum value</returns>
 private static T GetAttributeOfType<TEnum, T>(this TEnum value)
 where TEnum : struct, IConvertible
 where T : Attribute
 {
 return value.GetType()
 .GetMember(value.ToString())
 .First()
 .GetCustomAttributes(false)
 .OfType<T>()
 .LastOrDefault();
 }
}

And this is the extension method for strings for converting to title case:

 /// <summary>
 /// Converts camel case or pascal case to separate words with title case
 /// </summary>
 /// <param name="s"></param>
 /// <returns></returns>
 public static string ToSpacedTitleCase(this string s)
 {
 //https://stackoverflow.com/a/155486/150342
 CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
 TextInfo textInfo = cultureInfo.TextInfo;
 return textInfo
 .ToTitleCase(Regex.Replace(s, 
 "([a-z](?=[A-Z0-9])|[A-Z](?=[A-Z][a-z]))", "1ドル "));
 }
answered Jul 2, 2013 at 12:48

Comments

6

For some programmer humor, a one liner as a joke:

public static string GetDescription(this Enum value) => value.GetType().GetMember(value.ToString()).First().GetCustomAttribute<DescriptionAttribute>() is DescriptionAttribute attribute ? attribute.Description : string.Empty;

In a more readable form:

using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
public static class EnumExtensions
{
 // get description from enum:
 public static string GetDescription(this Enum value)
 {
 return value.GetType().
 GetMember(value.ToString()).
 First().
 GetCustomAttribute<DescriptionAttribute>() is DescriptionAttribute attribute
 ? attribute.Description
 : throw new Exception($"Enum member '{value.GetType()}.{value}' doesn't have a [DescriptionAttribute]!");
 }
 // get enum from description:
 public static T GetEnum<T>(this string description) where T : Enum
 {
 foreach (FieldInfo fieldInfo in typeof(T).GetFields())
 {
 if (fieldInfo.GetCustomAttribute<DescriptionAttribute>() is DescriptionAttribute attribute && attribute.Description == description)
 return (T)fieldInfo.GetRawConstantValue();
 }
 throw new Exception($"Enum '{typeof(T)}' doesn't have a member with a [DescriptionAttribute('{description}')]!");
 }
}
answered Sep 8, 2020 at 19:58

1 Comment

I actually prefer the first implementation ironically enough. I'm more accustomed to functional style programming in C# and found it to be more readable. :)
5

Performance matters

If you want better performance this is the way to go:

public static class AdvancedEnumExtensions
{
 /// <summary>
 /// Gets the custom attribute <typeparamref name="T"/> for the enum constant, if such a constant is defined and has such an attribute; otherwise null.
 /// </summary>
 public static T GetCustomAttribute<T>(this Enum value) where T : Attribute
 {
 return GetField(value)?.GetCustomAttribute<T>(inherit: false);
 }
 /// <summary>
 /// Gets the FieldInfo for the enum constant, if such a constant is defined; otherwise null.
 /// </summary>
 public static FieldInfo GetField(this Enum value)
 {
 ulong u64 = ToUInt64(value);
 return value
 .GetType()
 .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
 .Where(f => ToUInt64(f.GetRawConstantValue()) == u64)
 .FirstOrDefault();
 }
 /// <summary>
 /// Checks if an enum constant is defined for this enum value
 /// </summary>
 public static bool IsDefined(this Enum value)
 {
 return GetField(value) != null;
 }
 /// <summary>
 /// Converts the enum value to UInt64
 /// </summary>
 public static ulong ToUInt64(this Enum value) => ToUInt64((object)value);
 private static ulong ToUInt64(object value)
 {
 switch (Convert.GetTypeCode(value))
 {
 case TypeCode.SByte:
 case TypeCode.Int16:
 case TypeCode.Int32:
 case TypeCode.Int64:
 return unchecked((ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture));
 case TypeCode.Byte:
 case TypeCode.UInt16:
 case TypeCode.UInt32:
 case TypeCode.UInt64:
 case TypeCode.Char:
 case TypeCode.Boolean:
 return Convert.ToUInt64(value, CultureInfo.InvariantCulture);
 default: throw new InvalidOperationException("UnknownEnumType");
 }
 }
}

Why does this have better performance?

Because the built-in methods all use code very similar to this except they also run a bunch of other code we don't care about. C#'s Enum code is quite horrible in general.

The above code has been Linq-ified and streamlined so it only contains the bits we care about.

Why is the built-in code slow?

First regarding Enum.ToString() -vs- Enum.GetName(..)

Always use the latter. (Or better yet neither, as will become clear below.)

ToString() uses the latter internally, but again, also does a bunch of other stuff we don't want, e.g. tries to combine flags, print out numbers etc. We are only interested in constants defined inside the enum.

Enum.GetName in turn gets all fields, creates a string array for all names, uses the above ToUInt64 on all of their RawConstantValues to create an UInt64 array of all values, sorts both arrays according to the UInt64 value, and finally gets the name from the name-array by doing a BinarySearch in the UInt64-array to find the index of the value we wanted.

...and then we throw the fields and the sorted arrays away use that name to find the field again.

One word: "Ugh!"

answered Mar 4, 2020 at 15:55

2 Comments

This could be further improved for performance with some caching, but then it goes into "over-engineering" land. That's where I decided that using an external library would be the best approach.
You can abuse the type-system by making the extensions generic and then cache in static fields. You basically shove the performance responsibility onto the type system, but it's very easy to implement and thread-safety is trivial to uphold since you don't have to deal with mutability. The above would still be the component that does the actual "work" - caching should be implemented as a layer above that.
4

Get the dictionary from enum.

public static IDictionary<string, int> ToDictionary(this Type enumType)
{
 return Enum.GetValues(enumType)
 .Cast<object>()
 .ToDictionary(v => ((Enum)v).ToEnumDescription(), k => (int)k); 
}

Now call this like...

var dic = typeof(ActivityType).ToDictionary();

EnumDecription Ext Method

public static string ToEnumDescription(this Enum en) //ext method
{
 Type type = en.GetType();
 MemberInfo[] memInfo = type.GetMember(en.ToString());
 if (memInfo != null && memInfo.Length > 0)
 {
 object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
 if (attrs != null && attrs.Length > 0)
 return ((DescriptionAttribute)attrs[0]).Description;
 }
 return en.ToString();
}
public enum ActivityType
{
 [Description("Drip Plan Email")]
 DripPlanEmail = 1,
 [Description("Modification")]
 Modification = 2,
 [Description("View")]
 View = 3,
 [Description("E-Alert Sent")]
 EAlertSent = 4,
 [Description("E-Alert View")]
 EAlertView = 5
}
answered Jul 1, 2014 at 12:54

Comments

4

I this answer to setup a combo box from an enum attributes which was great.

I then needed to code the reverse so that I can get the selection from the box and return the enum in the correct type.

I also modified the code to handle the case where an attribute was missing

For the benefits of the next person, here is my final solution

public static class Program
{
 static void Main(string[] args)
 {
 // display the description attribute from the enum
 foreach (Colour type in (Colour[])Enum.GetValues(typeof(Colour)))
 {
 Console.WriteLine(EnumExtensions.ToName(type));
 }
 // Get the array from the description
 string xStr = "Yellow";
 Colour thisColour = EnumExtensions.FromName<Colour>(xStr);
 Console.ReadLine();
 }
 public enum Colour
 {
 [Description("Colour Red")]
 Red = 0,
 [Description("Colour Green")]
 Green = 1,
 [Description("Colour Blue")]
 Blue = 2,
 Yellow = 3
 }
}
public static class EnumExtensions
{
 // This extension method is broken out so you can use a similar pattern with 
 // other MetaData elements in the future. This is your base method for each.
 public static T GetAttribute<T>(this Enum value) where T : Attribute
 {
 var type = value.GetType();
 var memberInfo = type.GetMember(value.ToString());
 var attributes = memberInfo[0].GetCustomAttributes(typeof(T), false);
 // check if no attributes have been specified.
 if (((Array)attributes).Length > 0)
 {
 return (T)attributes[0];
 }
 else
 {
 return null;
 }
 }
 // This method creates a specific call to the above method, requesting the
 // Description MetaData attribute.
 public static string ToName(this Enum value)
 {
 var attribute = value.GetAttribute<DescriptionAttribute>();
 return attribute == null ? value.ToString() : attribute.Description;
 }
 /// <summary>
 /// Find the enum from the description attribute.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="desc"></param>
 /// <returns></returns>
 public static T FromName<T>(this string desc) where T : struct
 {
 string attr;
 Boolean found = false;
 T result = (T)Enum.GetValues(typeof(T)).GetValue(0);
 foreach (object enumVal in Enum.GetValues(typeof(T)))
 {
 attr = ((Enum)enumVal).ToName();
 if (attr == desc)
 {
 result = (T)enumVal;
 found = true;
 break;
 }
 }
 if (!found)
 {
 throw new Exception();
 }
 return result;
 }
}

}

wonea
4,98917 gold badges91 silver badges143 bronze badges
answered Nov 25, 2014 at 11:45

1 Comment

Man I have seen so many stupid and unexplained solutions, and yours killed it. Thank you a lot <3
3

I implemented this extension method to get the description from enum values. It works for all kind of enums.

public static class EnumExtension
{
 public static string ToDescription(this System.Enum value)
 {
 FieldInfo fi = value.GetType().GetField(value.ToString());
 var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
 return attributes.Length > 0 ? attributes[0].Description : value.ToString();
 }
}
answered May 21, 2013 at 14:32

1 Comment

generic version of the same solution is already posted. imo, better.
3

Here's the .NET Core version of AdamCrawford's answer, using System.Reflection.TypeExtensions;

public static class EnumHelper
{
 /// <summary>
 /// Gets an attribute on an enum field value
 /// </summary>
 /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
 /// <param name="enumVal">The enum value</param>
 /// <returns>The attribute of type T that exists on the enum value</returns>
 /// <example>string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;</example>
 public static T GetAttributeOfType<T>(this Enum enumVal) where T : System.Attribute
 {
 var type = enumVal.GetType();
 var memInfo = type.GetMember(enumVal.ToString());
 IEnumerable<Attribute> attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
 return (T)attributes?.ToArray()[0];
 }
}
answered Oct 12, 2016 at 19:45

Comments

3

Adding my solution for Net Framework and NetCore.

I used this for my Net Framework implementation:

public static class EnumerationExtension
{
 public static string Description( this Enum value )
 {
 // get attributes 
 var field = value.GetType().GetField( value.ToString() );
 var attributes = field.GetCustomAttributes( typeof( DescriptionAttribute ), false );
 // return description
 return attributes.Any() ? ( (DescriptionAttribute)attributes.ElementAt( 0 ) ).Description : "Description Not Found";
 }
}

This doesn't work for NetCore so I modified it to do this:

public static class EnumerationExtension
{
 public static string Description( this Enum value )
 {
 // get attributes 
 var field = value.GetType().GetField( value.ToString() );
 var attributes = field.GetCustomAttributes( false );
 // Description is in a hidden Attribute class called DisplayAttribute
 // Not to be confused with DisplayNameAttribute
 dynamic displayAttribute = null;
 if (attributes.Any())
 {
 displayAttribute = attributes.ElementAt( 0 );
 }
 // return description
 return displayAttribute?.Description ?? "Description Not Found";
 }
}

Enumeration Example:

public enum ExportTypes
{
 [Display( Name = "csv", Description = "text/csv" )]
 CSV = 0
}

Sample Usage for either static added:

var myDescription = myEnum.Description();
answered Jan 5, 2017 at 16:49

Comments

3

Bryan Rowe and AdamCrawford thanks for your answers!

But if somebody need method for get Discription (not extension) you can use it:

string GetEnumDiscription(Enum EnumValue)
 {
 var type = EnumValue.GetType();
 var memInfo = type.GetMember(EnumValue.ToString());
 var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
 return (attributes.Length > 0) ? ((DescriptionAttribute)attributes[0]).Description : null;
 }
answered Oct 29, 2020 at 8:20

Comments

2

Taking advantage of some of the newer C# language features, you can reduce the line count:

public static TAttribute GetEnumAttribute<TAttribute>(this Enum enumVal) where TAttribute : Attribute
{
 var memberInfo = enumVal.GetType().GetMember(enumVal.ToString());
 return memberInfo[0].GetCustomAttributes(typeof(TAttribute), false).OfType<TAttribute>().FirstOrDefault();
}
public static string GetEnumDescription(this Enum enumValue) => enumValue.GetEnumAttribute<DescriptionAttribute>()?.Description ?? enumValue.ToString();
wonea
4,98917 gold badges91 silver badges143 bronze badges
answered Jul 17, 2016 at 12:35

Comments

2

Model

The model in which we fill our values

public class MemberTypeModel : IDto
{
 public string MemberAttributeName { get; set; }
 public string MemberName { get; set; }
 public int MemberValue { get; set; }
}

Enum

Our target is the enum

public enum MemberType
{
 [FieldText("Yönetim Kurul Üyesi")]
 BoardManager = 0,
 [FieldText("Temsilci")]
 Representative = 1,
 [FieldText("Üye")]
 Member = 2
}

Helper Method

The helper method we will use to fetch the custom attribute object

public T GetMemberCustomText<T>(MemberType memberType) where T : Attribute
{
 var enumType = memberType.GetType();
 var name = Enum.GetName(enumType, memberType);
 return enumType.GetField(name).GetCustomAttributes(false).OfType<T>().SingleOrDefault();
}

Get Method

First we pull enum values and cast them to enum type. Then, with the Linq selection query we know;

  • MemberAttributeName field with helper method,
  • MemberName field with Enum.GetName method,
  • Casting the MemberValue field to an int type as well, We fill it out and turn it into a list.

public List<MemberTypeModel> GetMemberTypes()
{
 var memberTypes = Enum.GetValues(typeof(MemberType))
 .Cast<MemberType>()
 .Select(et => new MemberTypeModel
 {
 MemberAttributeName = GetMemberCustomText<FieldText>(et).Text,
 MemberName = Enum.GetName(et.GetType(), et),
 MemberValue = (int)et
 }).ToList();
 return memberTypes;
}
answered Nov 3, 2021 at 23:19

Comments

1
 public enum DataFilters
 {
 [Display(Name= "Equals")]
 Equals = 1,// Display Name and Enum Name are same 
 [Display(Name= "Does Not Equal")]
 DoesNotEqual = 2, // Display Name and Enum Name are different 
 }

Now it will produce error in this case 1 "Equals"

public static string GetDisplayName(this Enum enumValue)
 {
 var enumMember = enumValue.GetType().GetMember(enumValue.ToString()).First();
 return enumMember.GetCustomAttribute<DisplayAttribute>() != null ? enumMember.GetCustomAttribute<DisplayAttribute>().Name : enumMember.Name;
 }

so if it is same return enum name rather than display name because enumMember.GetCustomAttribute() gets null if displayname and enum name are same.....

answered May 4, 2018 at 10:32

1 Comment

This solution fetches the attribute twice, which causes an unnecessary overhead. Consider fetching it once, and if it's not null, return it's Name property. For example var attr = enumMember.GetCustomAttribute<DisplayAttribute>(); return attr != null ? attr.Name : enumMember.Name;
1

The NuGet package Enums.Net has good support for this:

var value = FunkyAttributesEnum.NameWithoutSpaces1;
string description = value.AsString(EnumFormat.Description); // => "Name With Spaces1"

The package is simple, intuitive, and complete.
It's type-safe and has cache to avoid recurring reflection.

The GitHub repository has more information, including the limitations of the native Enum and a demo of functionality:

  • Getting attributes;
  • Flag operations;
  • Enum formats (for ToString or to parse the enum from string);
  • Rich iteration of all values with Enums.GetMembers<MyEnum>();
  • Etc.
answered Nov 25, 2022 at 17:50

Comments

0

This extension method will obtain a string representation of an enum value using its XmlEnumAttribute. If no XmlEnumAttribute is present, it falls back to enum.ToString().

public static string ToStringUsingXmlEnumAttribute<T>(this T enumValue)
 where T: struct, IConvertible
{
 if (!typeof(T).IsEnum)
 {
 throw new ArgumentException("T must be an enumerated type");
 }
 string name;
 var type = typeof(T);
 var memInfo = type.GetMember(enumValue.ToString());
 if (memInfo.Length == 1)
 {
 var attributes = memInfo[0].GetCustomAttributes(typeof(System.Xml.Serialization.XmlEnumAttribute), false);
 if (attributes.Length == 1)
 {
 name = ((System.Xml.Serialization.XmlEnumAttribute)attributes[0]).Name;
 }
 else
 {
 name = enumValue.ToString();
 }
 }
 else
 {
 name = enumValue.ToString();
 }
 return name;
}
answered Aug 8, 2013 at 4:04

Comments

0

And if you want the full list of names you can do something like

typeof (PharmacyConfigurationKeys).GetFields()
 .Where(x => x.GetCustomAttributes(false).Any(y => typeof(DescriptionAttribute) == y.GetType()))
 .Select(x => ((DescriptionAttribute)x.GetCustomAttributes(false)[0]).Description);
answered Jul 5, 2016 at 12:56

Comments

0

Answer: How can I retrieve the attributes of an enum value?

In modern C#, you can efficiently retrieve attributes using the EnumCentricStatusManagement library. It simplifies attribute handling and centralizes enum-based management.

Steps:
1.Install the library via NuGet:

 dotnet add package EnumCentricStatusManagement

2.Define your enum with attributes: using EnumCentricStatusManagement.Attributes;

public enum Status
{
 [Status("Operation successful", StatusType.Success)]
 Success,
 [Status("An error occurred", StatusType.Error)]
 Error
}

3.Retrieve attributes at runtime:

using EnumCentricStatusManagement.Helpers;
var status = Status.Success;
var attribute = EnumHelper.GetAttribute<StatusAttribute>(status);
if (attribute != null)
{
 Console.WriteLine($"Message: {attribute.Message}");
}

This approach eliminates the need for complex reflection logic and provides a clean, centralized solution for managing enums with attributes.

Note: For more details and advanced usage, you can refer to the EnumCentricStatusManagement GitHub repository.

answered Dec 8, 2024 at 19:22

Comments

0

This question is pretty outdated, most of these answers even use reflection, run slowly and allocate memory

In 2025 your options are:

Option 1: source generators

Use source generators like NetEscapades.EnumGenerators from Andrew Lock. Or google for an alternative, there's plenty. This is the fastest way.

Option 2: cache your output

If you don't want an external dependency - cache the return.

public static string GetEnumDescription<T>(this T value) where T : struct, Enum
{
 return EnumDescriptionCache<T>.GetDescription(value);
}
private static class EnumDescriptionCache<T> where T : struct, Enum
{
 private static readonly ConcurrentDictionary<T, string> _enumDescriptionCache = new();
 public static string GetDescription(T value)
 {
 return _enumDescriptionCache.GetOrAdd(value, static value =>
 {
 FieldInfo field = value.GetType().GetField(value.ToString());
 var attribute = field.GetCustomAttribute<DescriptionAttribute>();
 return attribute?.Description ?? value.ToString();
 });
 }
}
//usage
FunkyAttributesEnum.NameWithoutSpaces1.GetEnumDescription();

Benchmarks

Method Mean Error StdDev Gen0 Allocated
Accepted_Answer 315.380 ns 49.3414 ns 2.7046 ns 0.0315 264 B
This_answer 1.247 ns 0.7049 ns 0.0386 ns - -

315X faster

answered Aug 6 at 11:23

Comments

-1

Alternatively, you could do the following:

Dictionary<FunkyAttributesEnum, string> description = new Dictionary<FunkyAttributesEnum, string>()
 {
 { FunkyAttributesEnum.NameWithoutSpaces1, "Name With Spaces1" },
 { FunkyAttributesEnum.NameWithoutSpaces2, "Name With Spaces2" },
 };

And get the description with the following:

string s = description[FunkyAttributesEnum.NameWithoutSpaces1];

In my opinion this is a more efficient way of doing what you want to accomplish, as no reflection is needed..

answered Nov 25, 2009 at 19:28

5 Comments

Sure, but reflection isn't nearly as bad as people make it out to be.
Not saying it's bad -- I use it all the time. It is often used needlessly, though. :)
This solution moves the description away from the enum itself, creating at least two big problems. First, if someone adds a new enum constant , they will need to know to go to this other place to add an entry there as well. Attributes are a clear sign to a maintainer of what they need to do. My second problem with it is that it's just a lot more code. Attributes are compact.
@scott but it does let you specify your own order, and exclude values you don't want to display which is nearly always what I actually want
@Simon_Weaver be careful, the documentation says that «The order in which the items are returned (from the dictionary) is undefined.».
-1

Guys if it helps I will share with you my solution: Definition of Custom attribute:

 [AttributeUsage(AttributeTargets.Field,AllowMultiple = false)]
public class EnumDisplayName : Attribute
{
 public string Name { get; private set; }
 public EnumDisplayName(string name)
 {
 Name = name;
 }
}

Now because I needed it inside of HtmlHelper definition of HtmlHelper Extension:

public static class EnumHelper
{
 public static string EnumDisplayName(this HtmlHelper helper,EPriceType priceType)
 {
 //Get every fields from enum
 var fields = priceType.GetType().GetFields();
 //Foreach field skipping 1`st fieldw which keeps currently sellected value
 for (int i = 0; i < fields.Length;i++ )
 {
 //find field with same int value
 if ((int)fields[i].GetValue(priceType) == (int)priceType)
 {
 //get attributes of found field
 var attributes = fields[i].GetCustomAttributes(false);
 if (attributes.Length > 0)
 {
 //return name of found attribute
 var retAttr = (EnumDisplayName)attributes[0];
 return retAttr.Name;
 }
 }
 }
 //throw Error if not found
 throw new Exception("Błąd podczas ustalania atrybutów dla typu ceny allegro");
 }
}

Hope it helps

Ranco
8932 gold badges13 silver badges44 bronze badges
answered Dec 29, 2013 at 10:56

Comments

-1

Alternatively, you could do the following:

List<SelectListItem> selectListItems = new List<SelectListItem>();
 foreach (var item in typeof(PaymentTerm).GetEnumValues())
 {
 var type = item.GetType();
 var name = type.GetField(item.ToString()).GetCustomAttributesData().FirstOrDefault()?.NamedArguments.FirstOrDefault().TypedValue.Value.ToString();
 selectListItems.Add(new SelectListItem(name, type.Name));
 }
answered Nov 11, 2019 at 15:03

Comments

-1

I have created an extension method that will return description of all the elements in an enum in C#.

public static List<string> GetAllEnumDescriptions(this Type enumType)
 {
 try
 {
 var enumList = Enum.GetValues(enumType).Cast<Enum>().ToList();
 List<string> result = new List<string>();
 foreach (var enumItem in enumList)
 {
 result.Add(enumItem.EnumDescription());
 }
 return result;
 }
 catch (Exception ex)
 {
 return new List<string>();
 }
 }

This method will add the description of the elements in an enum using the inbuilt EnumDescription() extension method.

answered May 12, 2022 at 12:08

1 Comment

using the inbuilt EnumDescription() extension method there is no such built-in method.
-2

This is how I solved it without using custom helpers or extensions with .NET core 3.1.

Class

public enum YourEnum
{
 [Display(Name = "Suryoye means Arameans")]
 SURYOYE = 0,
 [Display(Name = "Oromoye means Syriacs")]
 OROMOYE = 1,
}

Razor

@using Enumerations
foreach (var name in Html.GetEnumSelectList(typeof(YourEnum)))
{
 <h1>@name.Text</h1>
}
answered Feb 14, 2020 at 21:23

1 Comment

consider answering the question using more than how you solved 'it' - start by acknowledging the problem and explaining how you think this solves 'it'. Remember your answer could be taken out of context in some years from now and it would then be almost useless. Adding more to it, adding some context would level up your answer and its possible historical/archival relevance

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.