【问题标题】:.NET Flag Enum get Attributes from values.NET 标志枚举从值中获取属性
【发布时间】:2013-08-14 03:48:30
【问题描述】:

问候 StackOverflow,

如果我有一个带有 Flag 属性的枚举类型以及这个枚举类型中的值具有自己的属性,我如何检索所有适当的属性?

例如:

[Flags()]
enum MyEnum
{
    [EnumDisplayName("Enum Value 1")]
    EnumValue1 = 1,
    [EnumDisplayName("Enum Value 2")]
    EnumValue2 = 2,
    [EnumDisplayName("Enum Value 3")]
    EnumValue3 = 4,
}

void Foo()
{
    var enumVar = MyEnum.EnumValue2 | MyEnum.EnumValue3;

    // get a collection of EnumDisplayName attribute objects from enumVar
    ...
}

【问题讨论】:

    标签: c# .net enums custom-attributes


    【解决方案1】:

    使用 Linq 的快速而肮脏的方式:

    IEnumerable<EnumDisplayNameAttribute> attributes = 
        Enum.GetValues(typeof(MyEnum))
            .Cast<MyEnum>()
            .Where(v => enumVar.HasFlag(v))
            .Select(v => typeof(MyEnum).GetField(v.ToString()))
            .Select(f => f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), false)[0])
            .Cast<EnumDisplayNameAttribute>();
    

    或者在查询语法中:

    IEnumerable<EnumDisplayNameAttribute> attributes = 
        from MyEnum v in Enum.GetValues(typeof(MyEnum))
        where enumVar.HasFlag(v)
        let f = typeof(MyEnum).GetField(v.ToString())
        let a = f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), false)[0]
        select ((EnumDisplayNameAttribute)a);
    

    或者,如果每个字段可能有多个属性,您可能希望这样做:

    IEnumerable<EnumDisplayNameAttribute> attributes = 
        Enum.GetValues(typeof(MyEnum))
            .Cast<MyEnum>()
            .Where(v => enumVar.HasFlag(v))
            .Select(v => typeof(MyEnum).GetField(v.ToString()))
            .SelectMany(f => f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), false))
            .Cast<EnumDisplayNameAttribute>();
    

    或者在查询语法中:

    IEnumerable<EnumDisplayNameAttribute> attributes = 
        from MyEnum v in Enum.GetValues(typeof(MyEnum))
        where enumVar.HasFlag(v))
        let f = typeof(MyEnum).GetField(v.ToString())
        from EnumDisplayNameAttribute a in f.GetCustomAttributes(typeof(EnumDisplayNameAttribute), false)
        select a;
    

    【讨论】:

    • 我可能需要更多的咖啡,但Where(v =&gt; (enumVar &amp; v) != v) 子句是否正确?不应该是(enumVar &amp; v) == v 还是(enumVar &amp; v) != 0?编辑:没关系,让我喝杯咖啡。 EDITx2:不,我想我是对的。天哪,我疯了。
    • @ChrisSinclair 是的,我首先有!= 0,但后来我意识到== v 可能更好(但没有修复!=)但实际上.HasFlag(v) 比IMO 都好.我想我也需要咖啡:p
    • 我使用FirstOrDefault() 而不是索引器[0] 来处理可能没有此属性的标志。然后我检查列表中的空值并做出适当的反应。
    猜你喜欢
    • 2011-02-16
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    相关资源
    最近更新 更多