2013-10-25 67 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