Click here to Skip to main content
15,888,133 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am trying to get custom attribute on Enum value using an extension method that each enum value can use. When I try to call GetCustomAttributes it always return nothing.

What I have tried:

Basically I have a test enum that have a custom attribute with parameter 'name'

C#
private enum TestEnum
{
    [Enum("Whatever")]
    Unknown = 0
}


This is the extension method that is being used to retrieve 'Whatever'
C#
public static string ToDisplayName(this Enum value)
{
    var type = value.GetType();
    var attributes = type.GetTypeInfo().GetCustomAttributes(typeof(Enum),true);

    return ((EnumAttribute)attributes[0]).Name;
}


attributes variable is always empty.

And this is the usage:
C#
var testEnum = TestEnum.Unknown;
var result = testEnum.ToDisplayName();


Thanks in advance
Posted
Updated 23-Sep-19 5:01am
v2

I think you want to use the built-in DescriptionAttribute, which will make the code simpler:
public static class EnumExtensions
{
    public static string ToDisplayName(this Enum value)
    {
        Type type = value.GetType();
        
        MemberInfo[] memInfo = type.GetMember(value.ToString());

        // no attributes found ?
        if (memInfo.Length == 0) return string.Empty;
       
        // cast to Array or List required 
        // an IEnumerable of DescriptionAttribute cannot be indexed !
        DescriptionAttribute[] attributes = memInfo[0].GetCustomAttributes<DescriptionAttribute>(false).ToArray();

        // handle value without description
        return (attributes.Length == 0) ? string.Empty : attributes[0].Description;
    }
}
Usage:
public enum TestEnum
{
    [Description("Whatever")]
    Unknown = 0,
    NoDescription
}

// sample calls
string des0 = TestEnum.Unknown.ToDisplayName();
string des1 = TestEnum.NoDescription.ToDisplayName();
 
Share this answer
 
v4
To add to Bill's answer, there are a couple of problems with your original code.
C#
var type = value.GetType();
var attributes = type.GetTypeInfo().GetCustomAttributes(...);
You're looking for attributes on the enum type itself, rather than attributes on the enum member. So:
C#
[Enum("...")] private enum TestEnum { ... }
would match, but:
C#
private enum TestEnum { [Enum("...")] Unknown }
wouldn't.

You need to find the field which corresponds to the enum value you're working with, and look for the attributes on that field.

C#
.GetCustomAttributes(typeof(Enum), true);
The type you pass as the first parameter here needs to be the attribute type you're looking for. But instead of passing typeof(EnumAttribute), you're passing typeof(Enum). That is the System.Enum class, which is not an attribute, and won't match your custom attribute.

C#
return ((EnumAttribute)attributes[0]).Name;
GetCustomAttributes will return an empty array if there are no matching attributes. If that happens, your code will throw an IndexOutOfRangeException. You should test whether the attribute was found, and return a suitable alternative if it wasn't.

You can fix your code quite easily:
C#
public static string ToDisplayName(this Enum value)
{
    var enumType = value.GetType().GetTypeInfo();
    var valueField = enumType.GetDeclaredField(value.ToString());
    var attributes = valueField.GetCustomAttributes<EnumAttribute>(false);
    if (attributes.Length == 0) return value.ToString();
    return attributes[0].Name;
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900