2011-09-19 128 views
30

我不知道一個通​​用的方法爲enum標誌的所有位設置爲1 枚舉標誌的所有位我只是想有一個enum返回所有的比較,無論其他枚舉。如何設置

而這段代碼有效;

[Flags] 
public enum SomeRightEnum : uint 
{ 
    CanDoNothing = 0, 
    CanDoSomething = 1 << 0, 
    CanDoSomethingElse = 1 << 1, 
    CanDoYetAnotherThing = 1 << 2, 
    ... 
    DoEverything = 0xFFFFFFFF 
} 

但在上面,因爲它是我們UINT設置的「F」的數目的代碼,如果它是int這是行不通的。

所以我會感激enum標誌的所有位設置爲1的通用方法,無論數據類型(i NT,int64uint等)

+1

嗯。枚舉的目的是描述相互排斥的選項。你似乎將它們用作一堆位掩碼的簡寫。 –

+1

@AFgone您在枚舉權上使用[Flags]屬性? –

+1

@Oli枚舉上的[Flags]屬性是爲此設計的。 –

回答

47

最簡單的大概是:

enum Foo 
{ 
    blah = 1, 
    .... 
    all = ~0 
} 

對於無符號基於枚舉:

enum Foo : uint 
{ 
    blah = 1, 
    .... 
    all = ~0u; 
} 
+0

當我試着這樣說它說:「不變的值'-1'不能轉換爲'uint'」 – AFgone

+1

只是演員然後,例如'unchecked((uint)〜0)' – leppie

+0

非常感謝這就是我正在尋找的 – AFgone

3
internal static class Program 
{ 
    private static void Main() 
    { 
     Console.WriteLine(Foo.Everything.HasFlag(Foo.None)); // False 
     Console.WriteLine(Foo.Everything.HasFlag(Foo.Baz)); // True 
     Console.WriteLine(Foo.Everything.HasFlag(Foo.Hello)); // True 
    } 
} 

[Flags] 
public enum Foo : uint 
{ 
    None = 1 << 0, 
    Bar = 1 << 1, 
    Baz = 1 << 2, 
    Qux = 1 << 3, 
    Hello = 1 << 4, 
    World = 1 << 5, 
    Everything = Bar | Baz | Qux | Hello | World 
} 

是這樣的,你想要什麼?

+0

但這不是其他枚舉,當我編輯或刪除枚舉我不得不改變「一切」 – AFgone

5

萬一有人疑惑: 我需要做同樣的建設WPF一個可綁定enumconverter。
由於我不知道Reflection中的值是什麼意思,我需要手動切換值(將它們綁定到複選框pe)
將Flagged enum的值設置爲-1以設置所有的位。
如果將其設置爲-1,並且取消標記所有值,則不會導致0,因爲所有未使用的位都不是未標記的。
這是笏最適合我的情況。

SomeRightEnum someRightEnum = SomeRightEnum.CanDoNothing; 
Type enumType = someRightEnum.GetType(); 
int newValue = 0; 
var enumValues = Enum.GetValues(enumType).Cast<int>().Where(e => e == 1 || e % 2 == 0); 
foreach (var value in enumValues) 
{ 
    newValue |= value; 
} 
Console.WriteLine(newValue); 

或者,如果你想擴展方法:

public static class FlagExtensions 
{ 
    public static TEnum AllFlags<TEnum>(this TEnum @enum) 
     where TEnum : struct 
    { 
     Type enumType = typeof(TEnum); 
     long newValue = 0; 
     var enumValues = Enum.GetValues(enumType); 
     foreach (var value in enumValues) 
     { 
      long v = (long)Convert.ChangeType(value, TypeCode.Int64); 
      if(v == 1 || v % 2 == 0) 
      { 
       newValue |= v; 
      } 
     } 
     return (TEnum)Enum.ToObject(enumType , newValue); 
    } 
} 
+0

使其成爲擴展'enum'系統類的名爲'AllFlags'的擴展方法。那麼它可以整齊地使用'enum。AllFlags(typeof(MyEnum))'no? –

+0

@ v.oddou我用一個返回(不可變)值的通用擴展更新了我的答案。我還刪除了一個缺省的非標誌值。 – Silvermind

18
[Flags] 
public enum MyEnum 
{ 
    None = 0, 
    First = 1 << 0, 
    Second = 1 << 1, 
    Third = 1 << 2, 
    Fourth = 1 << 3, 
    All = ~(-1 << 4) 
} 
+0

我喜歡這個選項,甚至比我通常的'-1'選項更好。我使用枚舉來跟蹤哪些任務被請求,並在任務完成時刪除標誌。然後,我的計劃是使用結果作爲退出代碼。所以這有助於維護任務枚舉。 – Schmalls

+1

我更喜歡'所有=〜(〜0 << 4)',因爲它更清晰一點。不是每個人都知道'-1'全是'1'。 –

+0

'None'不應該是'-1'?! – akhansari