5

Can somebody explain to me why Value.GetType().GetCustomAttribute returns null? I have looked at ten different tutorials on how to get the attributes for an enumerated type member. No matter which GetCustomAttribute* method I use, I get no custom attributes returned.

using System;
using System.ComponentModel;
using System.Reflection;

public enum Foo
{
    [Bar(Name = "Bar")]
    Baz,
}

[AttributeUsage(AttributeTargets.Field)]
public class BarAttribute : Attribute
{
    public string Name;
}

public static class FooExtensions
{
    public static string Name(this Foo Value)
    {
        return Value.GetType().GetCustomAttribute<BarAttribute>(true).Name;
    }
}
Tyler Crompton
  • 12,284
  • 14
  • 65
  • 94
  • 1
    Perhaps I should reword my question. I understand why `NullReferenceException` is thrown. What I don't understand is why `Value.GetType().GetCustomAttribute` returns `null`. – Tyler Crompton Jan 11 '13 at 19:45

5 Answers5

17

Because the attribute you are trying to retrieve has not been applied to the type; it has been applied to the field.

Therefore, rather than calling GetCustomAttributes on the type object, you need to call it on the FieldInfo object. In other words, you would need to do something more like this:

typeof(Foo).GetField(value.ToString()).GetCustomAttributes...
phoog
  • 42,068
  • 6
  • 79
  • 117
  • How would I apply it to the field rather than the type? – Tyler Crompton Jan 11 '13 at 19:43
  • 2
    You have applied the attribute to the feild – Dhawalk Jan 11 '13 at 19:45
  • @TylerCrompton as Dhawalk said, in your sample code, the attribute *is* applied to the field. That's why you're having this problem. That's also why the attribute's own AttributeUsage attribute is for AttributeTargets.Field. I've reworded and slightly expanded the answer. – phoog Jan 11 '13 at 19:47
2

phoog's explanation of the problem is correct. If you want an example of how to retrieve the attribute on an enum value, check out this answer.

Community
  • 1
  • 1
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
1

your attribute is at field level, whereas Value.GetType().GetCustomAttribute<BarAttribute>(true).Name would return attribute applied to enum Foo

Dhawalk
  • 1,257
  • 13
  • 28
0

I think you must rewrite FooExtension like this:

public static class FooExtensions
{
    public static string Name(this Foo Value)
    {
        string rv = string.Empty;
        FieldInfo fieldInfo = Value.GetType().GetField(Value.ToString());
        if (fieldInfo != null)
        {
            object[] customAttributes = fieldInfo.GetCustomAttributes(typeof (BarAttribute), true);
            if(customAttributes.Length>0 && customAttributes[0]!=null)
            {
                BarAttribute barAttribute = customAttributes[0] as BarAttribute;
                if (barAttribute != null)
                {
                    rv = barAttribute.Name;
                }
            }
        }

        return rv;
    }
}
Leigh
  • 28,765
  • 10
  • 55
  • 103
Milad
  • 379
  • 1
  • 16
0

I ended up rewriting it like this:

public static class FooExtensions
{
    public static string Name(this Foo Value)
    {
        var Type = Value.GetType();
        var Name = Enum.GetName(Type, Value);
        if (Name == null)
            return null;

        var Field = Type.GetField(Name);
        if (Field == null)
            return null;

        var Attr = Field.GetCustomAttribute<BarAttribute>();
        if (Attr == null)
            return null;

        return Attr.Name;
    }
}
Tyler Crompton
  • 12,284
  • 14
  • 65
  • 94