2017-07-31 95 views
0

我試圖創建一個擴展方法,該方法將返回包含所有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 /某些其他語言 - 我正在尋找一種擴展方法語言,所以我認爲它是適當的。 –

回答

5

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

0

可以遍歷枚舉從所有的值,然後篩選它們沒有包含到您的輸入值。

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>();