2013-10-25 66 views
3

我有這樣的方案,其中用戶有它的作用結合枚舉值與位標誌

NormalUser
護法
財經

兩個護法和金融是一個超級用戶

我如何檢查角色保管人是否是超級用戶

這是我的示例代碼..

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication3 
{ 
    public enum Role 
    { 
     NormalUser = 0, 
     Custodian = 1, 
     Finance = 2, 
     SuperUser = Custodian | Finance, 
     All = Custodian | Finance | NormalUser 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine("Normal: " + Convert.ToInt32(Role.NormalUser));    
      Console.WriteLine("Custodian: " + Convert.ToInt32(Role.Custodian)); 
      Console.WriteLine("Finance: " + Convert.ToInt32(Role.Finance));    
      Console.WriteLine("SuperUser: " + Convert.ToInt32(Role.SuperUser)); 
      Console.WriteLine("All: " + Convert.ToInt32(Role.All)); 

      Console.WriteLine(); 
      Console.WriteLine("Normal User is in All: {0}", Role.NormalUser == Role.All); 
      Console.WriteLine("Normal User is not a SuperUser: {0}", Role.NormalUser != Role.SuperUser); 
      Console.WriteLine("Normal User is not a Custodian: {0}", Role.NormalUser != Role.Custodian); 

      Console.WriteLine(); 
      Console.WriteLine("Custodian is in All: {0}", Role.Custodian == Role.All); 
      Console.WriteLine("Custodian is a SuperUser: {0}", Role.Custodian == Role.SuperUser); 
      Console.WriteLine("Custodian is a NormalUser: {0}", Role.Custodian == Role.NormalUser); 

      Console.WriteLine(); 
      Console.WriteLine("Finance is in All: {0}", Role.Finance == Role.All); 
      Console.WriteLine("Finance is a SuperUser: {0}", Role.Finance == Role.SuperUser); 
      Console.WriteLine("Finance is a NormalUser: {0}", Role.Finance == Role.NormalUser); 

      Console.ReadLine(); 
     } 
    } 
} 

,這是結果,如果我們運行

Normal: 0 
Custodian: 1 
Finance: 2 
SuperUser: 3 
All: 3 

Normal User is in All: False 
Normal User is not a SuperUser: True 
Normal User is not a Custodian: True 

Custodian is in All: False 
Custodian is a SuperUser: False 
Custodian is a NormalUser: False 

Finance is in All: False 
Finance is a SuperUser: False 
Finance is a NormalUser: False 

我期待一個

護法全部:真
護法是超級用戶:真
融資是全部:真
金融是一個超級用戶:真
普通用戶的所有:真

+0

可能重複[什麼\ [Flags \]枚舉屬性在C#中的含義?](http://stackoverflow.com/questions/8447/what-does-the -flags-enum-attribute-mean-in-c) – drzaus

回答

14

Enum.HasFlag是你想使用的

Console.WriteLine("Custodian is in All: {0}", Role.All.HasFlag(Role.Custodian)); 

只注意到你的枚舉應該這樣來定義與標誌屬性和值由2

[Flags] 
public enum Role 
{ 
    NormalUser = 1, 
    Custodian = 2, 
    Finance = 4, 
    SuperUser = Custodian | Finance, 
    All = Custodian | Finance | NormalUser 
} 

權力隔開的2的冪用於標記的枚舉的原因是,每個電源的2表示的二進制表示被設置一個唯一的位:

NormalUser = 1 = 00000001 
Custodian = 2 = 00000010 
Finance = 4 = 00000100 
Other  = 8 = 00001000 

因爲在枚舉的每個項目具有獨特的位置,這允許它們通過設置它們各自的結合位。

SuperUser = 6 = 00000110 = Custodian + Finance 
All  = 7 = 00000111 = NormalUser + Custodian + Finance 
NormOther = 9 = 00001001 = NormalUser + Other 

請注意,二進制形式中的每個1如何與上面部分中爲該標誌設置的位對齊。

+0

謝謝..我明白了..它的工作原理.. –

+0

什麼是間隔原因由2個值的權力。我知道你應該這樣做,但不知道爲什麼? – DonO

+0

@DonO剛剛更新了答案,以包括爲什麼使用2的權力的解釋,這是有點大,涵蓋了評論。希望它是有用的/有道理的。 –

1

可以旗屬性添加到枚舉

[Flags] 
public enum Role 
{ 
    NormalUser, 
    Custodian, 
    Finance, 
    SuperUser = Custodian | Finance, 
    All = Custodian | Finance | NormalUser 
} 

然後你可以檢查與此表達一個角色:

Role testRole = Role.Finance 
if(testRole & Role.SuperUser == Role.SuperUser){ 
     //testRole is SuperUser 
} 
1

我想這可能是How do you pass multiple enum values in C#?

重複

其中&位掩碼可以做到這一點。

((Role.NormalUser & Role.All) == Role.NormalUser) 

檢查這更接近你會得到如下:

0b0 & 0b11 == 0b0 

但是如果你讓說要檢查,如果超級用戶是在金融,你會得到如下:

((Role.SuperUser & Role.Finance) == Role.Finance) 

這將評估爲:

0b11 & 0b10 == 0b10 
+0

我不明白爲什麼。不是'a&b == c'只是'a == c && b == c'?如果是這樣,爲什麼不'a == c'?你的'Role.All'在這裏看起來不對。不要說你錯了。只是說我不知道​​爲什麼... – C4u

4

查看What does the [Flags] Enum Attribute mean in C#?以獲得更全面的解釋。

A「安全」的方式來聲明標誌是使用比特移位,以確保沒有重疊(由@DaveOwen's answer如前所述),而自己搞清楚數學:

[Flags] 
public enum MyEnum 
{ 
    None = 0, 
    First = 1 << 0, 
    Second = 1 << 1, 
    Third = 1 << 2, 
    Fourth = 1 << 3 
} 

還有Enum.HasFlag(可能是較新的。 NET比OP)檢查,而不是Expected & Testing == Expected