Testing for bitwise Enum values
我以前没有真正使用过位枚举,我只是想确保我的测试是正确的。我最感兴趣的是测试值none和all。我们从Web服务接收数据,该服务使用此枚举对某些数据片段进行分类。考虑到这一点,我假设下一个或全部都不会与任何其他价值结合起来。
给出以下按位枚举定义;
1 2 3 4 5 6 7 8 9 10 11 12 13 | [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的引述;
Use None as the name of the flag
enumerated constant whose value is
zero. You cannot use the None
enumerated constant in a bitwise AND
operation to test for a flag because
the result is always zero. However,
you can perform a logical, not a
bitwise, comparison between the
numeric value and the None enumerated
constant to determine whether any bits
in the numeric value are set.
此实例中的逻辑比较是否指枚举的普通相等测试?例如;
1 2 3 | TrainingComponentTypes tct = TrainingComponentTypes.None; if (tct == TrainingComponentTypes.None) { ... } |
为了进行逐位比较,我将执行以下操作:
1 2 3 4 | 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"); |
最后,当测试所有内容时,我尝试了逻辑和位比较,它们都返回相同的结果。我应该在这里用一个而不是另一个吗?例如;
1 2 3 4 5 6 7 | 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"); |
总之,我想知道下面关于位枚举的内容;
谢谢,克里斯
简短回答:是:)
比较长的:
1)所有操作都是在flags变量的整数值上执行的,因此您可以从这个角度来考虑这些操作。
2)是的。
3)任一工程。但是,值得注意的是,如果有人将一个无效的值推入一个变量,那么
1 2 3 | var badValue = (TrainingComponentTypes)128 | TrainingComponentTypes.All; // now badValue != TrainingComponentTypes.All // but (badValue & TrainingComponentTypes.All) == TrainingComponentTypes.All |
对于这一部分:
I am not sure if we'd ever receive a value where All was combined with other TrainingComponentTypes.
我不确定您是否完全理解枚举是如何在封面下工作的。
1 2 3 4 5 6 7 8 9 10 11 | 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 |
如您所见,所有这些值加在一起只是按位的
4)您可以使用它来检查"无"或"全部",但不能检查其他值。
值得注意的是,枚举上有一个方便的方法可以为您执行这些检查:enum.hasFlag。
Is my understanding of a logical comparison correct given my example above?
是的,在这个上下文中,逻辑意味着相等和不相等运算符。
Is the way I am performing a bitwise comparison correct?
是的,但有一个更简单的方法:
1 | tct.HasFlag(TrainingComponentTypes.Qualification) |
而不是:
1 | (tct & TrainingComponentTypes.Qualification) == TrainingComponentTypes.Qualification |
What is the right way to handle the"All" value (bitwise or logical). I am not sure if we'd ever receive a value where All was combined with other TrainingComponentTypes. I can't see why we would, but then, you never know?
我认为最好把
Am I right in assuming that switch statements basically shouldn't be used for bitwise enums (given none is appears to be a special case and requires a logical comparison)?
不,一点也不。请随意使用它们是
对。
是的
可以同时使用逻辑和位。用法取决于是否所有的位都被设置,或者只是按位还是按您定义的所有值。
是的,但不是因为
正如其他人所指出的,枚举包含hasFlag()。
1&2看起来不错
三。正如您所定义的那样,在不丢失数据的情况下不能与任何内容组合。如果"all"是您期望从服务器接收的实际值,那么您可能应该将其更改为128。
否则,它是一个方便的值,可以用来测试是否设置了任何值…除非将标志值作为二进制数据发送并打包到可能包含其他数据的字节中,否则不需要这样做。
4。可以使用switch语句,但如果/当您有多个标志的值时,这些语句将无法正常工作;如果存在有效标志组合的小子集,则它们仍然有用。
"3.What is the right way to handle the"All" value (bitwise or logical). I am not sure if we'd ever receive a value where All was combined with other TrainingComponentTypes. I can't see why we would, but"
似乎您误解了按位枚举值的工作方式。""all"总是与其他值组合在一起,实际上它是所有值的组合。查看枚举的二进制值:
NO=0,认可的课程=1,资格=10,单位=100,技能集=1000,统一上下文=10000,培训包=100000,认可的课程表=1000000,全部=1111111
这有助于你理解吗?
1和2-是的,但是有一种方法可以让阅读变得更容易:
1 2 | TrainingComponentTypes tct = TrainingComponentTypes.AccreditedCourse | TrainingComponentTypes.Qualification; Assert.IsTrue(tct.HasFlag(TrainingComponentTypes.AccreditedCourse),"Expected AccreditedCourse as part the enum"); |
3-我不确定你是否需要所有的价值。我会把它取下来。
是的,switch语句对于标志枚举通常没有意义。