测试按位Enum值

| 我以前从未真正使用过按位枚举,我只是想确保测试正确。我对测试值None和All最感兴趣。我们从Web服务接收数据,该服务利用此枚举对数据的某些部分进行分类。鉴于此,我假设“无”或“全”将与任何其他值组合。 给定以下按位枚举定义;
[System.FlagsAttribute()]
public enum TrainingComponentTypes : int
    {
        None = 0,
        AccreditedCourse = 1,
        Qualification = 2,
        Unit = 4,
        SkillSet = 8,
        UnitContextualisation = 16,
        TrainingPackage = 32,
        AccreditedCourseModule = 64,
        All = 127,
    }
我在该MSDN网站上阅读了有关FlagAttributes的以下引用;   使用None作为标志名称   枚举常量,其值为   零。您不能使用无   枚举常数按位与   用于测试标志的操作,因为   结果始终为零。然而,   您可以执行逻辑,而不是   按位比较   数值和无枚举   常数以确定是否有任何位   在数值中设置。 在这种情况下,逻辑比较是否引用枚举的正常相等性测试? 例如;
TrainingComponentTypes tct = TrainingComponentTypes.None; 
if (tct == TrainingComponentTypes.None) 
{ ... }
为了进行逐位比较,我正在执行以下操作;
 TrainingComponentTypes tct = TrainingComponentTypes.AccreditedCourse | TrainingComponentTypes.Qualification | TrainingComponentTypes.TrainingPackage;
 Assert.IsTrue((tct & TrainingComponentTypes.AccreditedCourse) == TrainingComponentTypes.AccreditedCourse, \"Expected AccreditedCourse as part the enum\");

 Assert.IsFalse((tct & TrainingComponentTypes.SkillSet) == TrainingComponentTypes.SkillSet, \"Found unexpected SkillSet as part the enum\");
最后,在测试所有对象时,我尝试了逻辑和按位比较,并且它们都返回相同的结果。我应该在这里使用另一个吗?例如;
TrainingComponentTypes tct = TrainingComponentTypes.All;

Assert.IsTrue((tct & TrainingComponentTypes.All) == TrainingComponentTypes.All, \"Expected All as part the enum\");
Assert.IsTrue((tct) == TrainingComponentTypes.All, \"Expected All as part the enum\");
// The follow also pass the assertion for a value of All
Assert.IsTrue((tct & TrainingComponentTypes.Qualification) == TrainingComponentTypes.Qualification, \"Expected Qualification as part the enum\");
Assert.IsTrue((tct & TrainingComponentTypes.TrainingPackage) == TrainingComponentTypes.TrainingPackage, \"Expected TrainingPackage as part the enum\");
因此,总而言之,我想了解以下有关逐位枚举的信息; 我对逻辑的理解 给我的例子比较正确 以上? 是我表演的方式 按位比较正确吗? 什么是处理“全部”的正确方法 值(按位或逻辑)。我不确定是否会收到将All与其他TrainingComponentTypes组合在一起的值。我不明白为什么要这么做,但是那你永远不知道吗? 我是正确的假设 声明基本上不应该是 用于按位枚举(无) 似乎是特例, 需要逻辑比较)? 谢谢, 克里斯     
已邀请:
简短答案:是:) 更长: 1)所有操作都是在flags变量的整数值上执行的,因此您可以在此方面进行思考。 2)是的。 3)都可以。但是,值得注意的是,如果有人将无效值推入变量,则
== TrainingComponentTypes.All
版本将失败。例如:
var badValue = (TrainingComponentTypes)128 | TrainingComponentTypes.All;
// now badValue != TrainingComponentTypes.All
// but (badValue & TrainingComponentTypes.All) == TrainingComponentTypes.All
对于这一部分:   我不确定是否会收到将All与其他TrainingComponentTypes组合在一起的值。 我不确定您是否完全理解枚举的工作原理。
The value of All is:
    127 = 1111111 (binary)

The other values are:
    AccreditedCourse       = 0000001
    Qualification          = 0000010
    Unit                   = 0000100
    SkillSet               = 0001000
    UnitContextualisation  = 0010000
    TrainingPackage        = 0100000
    AccreditedCourseModule = 1000000
如您所见,“ All”只是所有这些值的按位“ 7”。您无法将任何其他TraningComponentTypes与All结合使用,因为All已包含它们!另外,如果您自己将它们与with7组合在一起,则与直接使用All完全相同(因此,在枚举中定义All时很方便)。 4)您可以使用它来检查无或全部,但不能检查其他值。 值得注意的是,Enum上有一个方便的方法可以为您执行以下检查:Enum.HasFlag。     
  在上述示例中,我对逻辑比较的理解正确吗? 是的,在这种情况下,逻辑表示相等和不相等运算符。   我执行按位比较的方式正确吗? 是的,但是有一种更简单的方法:
Enum.HasFlag
。例如:
tct.HasFlag(TrainingComponentTypes.Qualification)
代替:
(tct & TrainingComponentTypes.Qualification) == TrainingComponentTypes.Qualification
  什么是处理\“ All \”值(按位或逻辑)的正确方法。我不确定是否会收到将All与其他TrainingComponentTypes组合在一起的值。我不明白为什么要这么做,但是那你永远不知道吗? 我认为最好将
enum
中的ѭ12定义为所有部分的按位“或”。但是,您会看到人们同时做这两种事情。   我是否假设基本上不应该将switch语句用于按位枚举(假设没有一种情况是特殊情况,并且需要进行逻辑比较),我是否正确? 一点都不。随时可以使用“ 14”语句。
case
值必须是常量,但可以是表达式,并经过相等性测试。编译器会告诉您是否做一些愚蠢的事情,例如尝试两次使用相同的
case
值。     
是。 是 逻辑和按位均可使用。用法取决于是否全部设置了所有位,还是仅定义了所有值的按位或。 是的,但不是因为ѭ17。开关比较单个值,而位字段显然可以具有多个值。 正如其他人指出的那样,Enum包含HasFlag()。     
1和2-是的,但是有一种方法可以使它更容易阅读:
TrainingComponentTypes tct = TrainingComponentTypes.AccreditedCourse | TrainingComponentTypes.Qualification;
Assert.IsTrue(tct.HasFlag(TrainingComponentTypes.AccreditedCourse), \"Expected AccreditedCourse as part the enum\");
3-我不确定您是否根本需要所有价值。我将其删除。 4-是的,对于Flags枚举,switch语句通常没有意义。     
  \“ 3。处理\” All \“值(按位或逻辑)的正确方法是什么。我不确定我们是否会收到将All与其他TrainingComponentTypes组合在一起的值。明白为什么会这样,但是\“ 似乎您误解了按位枚举值的工作方式。 \'All \'总是与其他值组合,实际上,它是所有值的组合。查看您的枚举的二进制值: 无= 0, AccreditedCourse = 1, 资格= 10, 单位= 100 SkillSet = 1000, UnitContextualisation = 10000, 培训包= 100000, AccreditedCourseModule = 1000000, 全部= 1111111 这有助于您的理解吗?     
1&2看起来不错 3。 您定义的所有内容都无法与任何内容组合,而不会丢失数据。如果\“ all \”是您希望从服务器收到的真实值,则应该将其更改为128。 否则,它是一个方便使用的值,可用于测试是否设置了任何值...除非标记值作为二进制数据发送并包装在可能包含其他数据的字节中,否则不需要此值。 4。 如果/当您的值具有多个标志时,可以使用switch语句,但效果不佳,如果有效标志组合的子集很小,它们仍然有用。     

要回复问题请先登录注册