从标记的枚举中获取描述属性

问题描述:

我试图创建一个扩展方法,该方法将返回包含所有Description属性的List<string>属性,仅用于给定的[Flags] Enum的设置值。从标记的枚举中获取描述属性

例如,假设我有以下枚举在我的C#代码中声明:

[Flags] 
public enum Result 
{ 
    [Description("Value 1 with spaces")] 
    Value1 = 1, 
    [Description("Value 2 with spaces")] 
    Value2 = 2, 
    [Description("Value 3 with spaces")] 
    Value3 = 4, 
    [Description("Value 4 with spaces")] 
    Value4 = 8 
} 

,然后有一个变量设置为:

Result y = Result.Value1 | Result.Value2 | Result.Value4; 

因此,呼叫我想创造会是:

List<string> descriptions = y.GetDescriptions(); 

而最终的结果将是:

descriptions = { "Value 1 with spaces", "Value 2 with spaces", "Value 4 with spaces" }; 

我已经创建了一个扩展方法得到单一描述属性对于不能有多个标志设置是大意如下的枚举:

public static string GetDescription(this Enum value) 
{ 
    Type type = value.GetType(); 
    string name = Enum.GetName(type, value); 
    if (name != null) 
    { 
     System.Reflection.FieldInfo field = type.GetField(name); 
     if (field != null) 
     { 
      DescriptionAttribute attr = 
        Attribute.GetCustomAttribute(field, 
        typeof(DescriptionAttribute)) as DescriptionAttribute; 
      if (attr != null) 
      { 
       return attr.Description; 
      } 
     } 
    } 
    return null; 
} 

而且我已经找到了一些答案在线如何获取给定枚举类型的所有Description属性(例如here),但是我在编写通用扩展方法时遇到问题,仅返回的描述列表,仅用于设置属性

任何帮助将非常感激。

谢谢!

+0

我编辑您的标题,因为当你*使用* C#你的问题不是*约* C#(这是没有必要使标签你的标题,除非它是它的一个组成部分) – slugster

+0

@slugster,我把它放在我的标题中,因为我想提到它是ac#问题而不是Java /某些其他语言 - 我正在寻找一种扩展方法语言,所以我认为它是适当的。 –

HasFlag是你的朋友。 :-)

下面的扩展方法使用上面发布的GetDescription扩展方法,所以确保你有。那么下面应该工作:

public static List<string> GetDescriptionsAsText(this Enum yourEnum) 
{  
    List<string> descriptions = new List<string>(); 

    foreach (Enum enumValue in Enum.GetValues(yourEnum.GetType())) 
    { 
     if (yourEnum.HasFlag(enumValue)) 
     { 
      descriptions.Add(enumValue.GetDescription()); 
     } 
    } 

    return descriptions; 
} 

注意HasFlag让您比较确定的标志给定的枚举值。在您的例子,如果你有

Result y = Result.Value1 | Result.Value2 | Result.Value4; 

然后

y.HasFlag(Result.Value1) 

应该是真实的,而

y.HasFlag(Result.Value3) 

将是错误的。

参见:https://msdn.microsoft.com/en-us/library/system.enum.hasflag(v=vs.110).aspx

+0

想要它! - 我很亲密! - 非常感谢您结束我的痛苦! :) –

+0

很高兴帮助。我现在更新了foreach变量的名称 - 使它感觉更通用一点(带有小的'g')。不会改变任何东西 - 看起来更整洁。 – bornfromanegg

可以遍历枚举从所有的值,然后筛选它们没有包含到您的输入值。

public static List<T> GetAttributesByFlags<T>(this Enum arg) where T: Attribute 
    { 
     var type = arg.GetType(); 
     var result = new List<T>(); 
     foreach (var item in Enum.GetValues(type)) 
     { 
      var value = (Enum)item; 
      if (arg.HasFlag(value)) // it means that '(arg & value) == value' 
      { 
       var memInfo = type.GetMember(value.ToString())[0]; 
       result.Add((T)memInfo.GetCustomAttribute(typeof(T), false)); 
      } 
     } 
     return result; 
    } 

,你会得到你想要的属性列表:

var arg = Result.Value1 | Result.Value4; 
List<DescriptionAttribute> attributes = arg.GetAttributesByFlags<DescriptionAttribute>();