测试多个标志值

时间:2019-03-31 08:44:58

标签: c# enum-flags

我有这个标志枚举:

public enum AssignmentType
{
    None = 0,
    Attendant = 1,
    ConductorCBS = 2,
    ReaderCBS = 4,
    Chairman = 8,
    Mike = 16,
    PlatformAttendant = 32,
    Prayer = 64,
    OCLM = 128,
    Sound = 256,
    Student = 512,
    Custom = 1024,
    Demonstration = 2048,
    Assistant = 4096
}

我现在想测试我的变量是否符合特定的标志条件。

我想确定我的变量是只有以下任意组合

  • None
  • Student
  • Assistant
  • Demonstration

因此,如果它具有任何其他枚举值,则该变量将无法满足测试要求。

首先,我从以下内容开始:

bool bIsPersonnel = true;

if (_Assignments == AssignmentType.None ||
    _Assignments == AssignmentType.Demonstration || 
    _Assignments == AssignmentType.Student ||
    _Assignments == AssignmentType.Assistant ||
    _Assignments == (AssignmentType.Demonstration | AssignmentType.Student))
{
    bIsPersonnel = false;
}

但是我很快意识到那里有多种选择。

有没有更简单的方法?

我看不出建议的答案有什么帮助。我想反向进行测试是最容易的。只要测试它是否有任何其他标志,我就知道它是人员!

5 个答案:

答案 0 :(得分:6)

您可以使用~按位取反运算符来应用掩码,以查找所有 invalid 标志,并检查是否已应用任何标志。

var valid = AssignmentType.Student | AssignmentType.Assistant | AssignmentType.Demonstration;
var invalid = ~valid; // Everything that isn't valid

if ((_Assignments & invalid) != 0)
{
    // There was at least one invalid flag, handle it appropriately
}

或检查其是否有效:

if ((_Assignment & invalid) == 0)
{
    // There are no invalid flags, handle it appropriately
}

或者,如果只是在设置单个布尔标志之后,就根本不需要if语句:

bool isPersonnel = ((assignment & invalid) != 0);

答案 1 :(得分:2)

(错误答案)

if ((_Assignments & AssignmentType.None) > 0
    || (_Assignments & AssignmentType.Student) > 0
    || (_Assignments & AssignmentType.Assistant) > 0
    || (_Assignments & AssignmentType.Demonstration) > 0
){
    bIsPersonnel = false;
}

正确答案:

var NonPersonnel = AssignmentType.None | AssignmentType.Student | AssignmentType.Assistant | Demonstration;
bool bIsPersonnel = (_Assignments | NonPersonnel) != NonPersonnel;

答案 2 :(得分:2)

我认为这可以按预期进行:

1711

以下是一些示例输出:

var flags =
    AssignmentType.None
    | AssignmentType.Student
    | AssignmentType.Assistant
    | AssignmentType.Demonstration;

bool bIsPersonnel =
    !(_Assignments == AssignmentType.None
        || (flags & _Assignments) == _Assignments);

答案 3 :(得分:0)

目前,我想出了进行反向测试的方法:

bool bIsPersonnel = false;

if(_Assignments.HasFlag(AssignmentType.Attendant | AssignmentType.ConductorCBS |
    AssignmentType.ReaderCBS | AssignmentType.Chairman |
    AssignmentType.Mike | AssignmentType.PlatformAttendant |
    AssignmentType.Prayer | AssignmentType.OCLM |
    AssignmentType.Sound | AssignmentType.Custom))
{
    bIsPersonnel = true;
}

这是最简单的,因为我们知道如果设置了这些标志中的任何一个,则该人为“人员”。其他标志不在图片中,我们不必测试多个标志配置。

答案 4 :(得分:0)

只需制作一个要检查的值掩码并用该值and掩码,这就是如何检查标志的方法,而不管标志的数量如何

if (0 != _Assignments &
     (AssignmentType.Demonstration | AssignmentType.Student | AssignmentType.Assistant))

无需检查AssignmentType.None,因为它本身不是标志,而只是等于0的保留值,用于检查是否未设置任何标志。如果组合中同时包含“无标志”和“其他标志”,那就没有意义了,对吗?如果您确实需要检查“无标志”条件,则请单独检查

if (_Assignments == AssignmentType.None || (0 != _Assignments &
         (AssignmentType.Demonstration | AssignmentType.Student | AssignmentType.Assistant)))

这也是Enum.HasFlag()检查标志的方式

public static void Main()
{
   DinnerItems myOrder = DinnerItems.Appetizer | DinnerItems.Entree |
                        DinnerItems.Beverage | DinnerItems.Dessert;
   DinnerItems flagValue = DinnerItems.Entree | DinnerItems.Beverage;
   Console.WriteLine("{0} includes {1}: {2}", 
                     myOrder, flagValue, myOrder.HasFlag(flagValue));
}