16

我有这种情况,用户有自己的角色

普通用户
托管
财务

托管人和财务都是超级用户

我如何检查角色保管人是否是超级用户

这是我的示例代码..

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

我期待一个

保管人在所有:真
保管人是超级用户:真
财务在所有:真
财务是超级用户:真
普通用户在所有:真

4

4 回答 4

52

Enum.HasFlag是您想要使用的

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

刚刚注意到,您的枚举应该像这样定义,其中 Flags 属性和值间隔为 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 如何与上一节中为标志设置的位对齐。

于 2013-10-25T06:27:30.857 回答
17

查看C# 中的 [Flags] 枚举属性是什么意思?以获得更彻底的解释。

声明标志的“更安全”的方法是使用位移来确保没有重叠(如@DaveOwen's answer所述),而无需自己弄清楚数学:

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

还有Enum.HasFlag(可能比 OP 更新的 .NET)用于检查,而不是Expected & Testing == Expected

于 2016-10-14T15:18:27.783 回答
2

您可以将标志属性添加到枚举

[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
 }
于 2013-10-25T06:33:58.033 回答
2

我认为这可能是您如何在 C# 中传递多个枚举值的副本?

& 位掩码可以解决问题的地方。

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

仔细检查,您将获得以下信息:

0b0 & 0b11 == 0b0

但是,如果您说要检查超级用户是否从事财务工作,您将获得以下信息:

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

这将评估为:

0b11 & 0b10 == 0b10
于 2013-10-25T06:48:18.080 回答