如何获取枚举的自定义属性值?

Joa*_*nge 40 .net c# reflection custom-attributes

我有一个枚举,每个成员都有一个自定义属性应用于它.如何检索存储在每个属性中的值?

现在我这样做:

var attributes = typeof ( EffectType ).GetCustomAttributes ( false );
foreach ( object attribute in attributes )
{
    GPUShaderAttribute attr = ( GPUShaderAttribute ) attribute;
    if ( attr != null )
        return attr.GPUShader;
}
return 0;
Run Code Online (Sandbox Code Playgroud)

另一个问题是,如果找不到,我应该返回什么?0是可以转换为任何枚举,对吧?这就是我回归的原因.

忘记提及,上面的代码为每个枚举成员返回0.

Geo*_*kis 36

尝试使用通用方法

属性:

class DayAttribute : Attribute
{
    public string Name { get; private set; }

    public DayAttribute(string name)
    {
        this.Name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

枚举:

enum Days
{
    [Day("Saturday")]
    Sat,
    [Day("Sunday")]
    Sun,
    [Day("Monday")]
    Mon, 
    [Day("Tuesday")]
    Tue,
    [Day("Wednesday")]
    Wed,
    [Day("Thursday")]
    Thu, 
    [Day("Friday")]
    Fri
}
Run Code Online (Sandbox Code Playgroud)

通用方法:

        public static TAttribute GetAttribute<TAttribute>(this Enum value)
        where TAttribute : Attribute
    {
        var enumType = value.GetType();
        var name = Enum.GetName(enumType, value);
        return enumType.GetField(name).GetCustomAttributes(false).OfType<TAttribute>().SingleOrDefault();
    }
Run Code Online (Sandbox Code Playgroud)

调用:

        static void Main(string[] args)
    {
        var day = Days.Mon;
        Console.WriteLine(day.GetAttribute<DayAttribute>().Name);
        Console.ReadLine();
    }
Run Code Online (Sandbox Code Playgroud)

结果:

星期一

  • 希望我能对此答案投票100次!!好东西 :-) (2认同)
  • 是的,可以工作..但是如果您没有为特定的 Enum 值声明属性,则您可能会在 null 上调用 .Name 。即你应该在调用 .Name 之前检查 day.GetAttribute&lt;DayAttribute&gt;() != null (2认同)

adr*_*nks 35

当你必须使用反射时,做你想做的事情有点麻烦:

public GPUShaderAttribute GetGPUShader(EffectType effectType)
{
    MemberInfo memberInfo = typeof(EffectType).GetMember(effectType.ToString())
                                              .FirstOrDefault();

    if (memberInfo != null)
    {
        GPUShaderAttribute attribute = (GPUShaderAttribute) 
                     memberInfo.GetCustomAttributes(typeof(GPUShaderAttribute), false)
                               .FirstOrDefault();
        return attribute;
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)

这将返回GPUShaderAttribute与枚举值中标记的实例相关的实例EffectType.你必须在EffectType枚举的特定值上调用它:

GPUShaderAttribute attribute = GetGPUShader(EffectType.MyEffect);
Run Code Online (Sandbox Code Playgroud)

获得属性的实例后,您可以从中获取在各个枚举值上标记的特定值.


小智 24

还有另一种方法可以使用泛型:

public static T GetAttribute<T>(Enum enumValue) where T: Attribute
{
    T attribute;

    MemberInfo memberInfo = enumValue.GetType().GetMember(enumValue.ToString())
                                    .FirstOrDefault();

    if (memberInfo != null)
    {
        attribute = (T) memberInfo.GetCustomAttributes(typeof (T), false).FirstOrDefault();
        return attribute;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个,但它没有考虑到同一属性有多个实例的可能性。我拿走了你所拥有的并将其修改为使用 T[] 而不是 T,然后删除了 GetCustomAttributes 上的 FirstOrDefault() 。 (2认同)