Mr *_*ose 17 c# comparison enums bit-manipulation bit
我以前没有真正使用过按位枚举,我只是想确保我的测试是正确的.我最感兴趣的是测试值None和All.我们从使用此枚举的Web服务接收数据,以对某些数据进行分类.鉴于此,我假设nether None和All将与任何其他值组合.
给出以下按位枚举定义;
[System.FlagsAttribute()]
public enum TrainingComponentTypes : int
{
None = 0,
AccreditedCourse = 1,
Qualification = 2,
Unit = 4,
SkillSet = 8,
UnitContextualisation = 16,
TrainingPackage = 32,
AccreditedCourseModule = 64,
All = 127,
}
Run Code Online (Sandbox Code Playgroud)
我在这个MSDN网站上阅读了关于FlagAttributes 的以下引用;
使用None作为其值为零的标志枚举常量的名称.您不能在按位AND运算中使用None枚举常量来测试标志,因为结果始终为零.但是,您可以在数值和None枚举常量之间执行逻辑而非按位比较,以确定是否设置了数值中的任何位.
此实例中的逻辑比较是否指向枚举的正常相等性测试?例如;
TrainingComponentTypes tct = TrainingComponentTypes.None;
if (tct == TrainingComponentTypes.None)
{ ... }
Run Code Online (Sandbox Code Playgroud)
为了进行逐位比较,我正在执行以下操作;
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");
Run Code Online (Sandbox Code Playgroud)
最后,在测试所有内容时,我尝试了逻辑和按位比较,并且它们都返回相同的内容.我应该在这里使用一个吗?例如;
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");
Run Code Online (Sandbox Code Playgroud)
总而言之,我想知道关于Bitwise枚举的以下内容;
谢谢,克里斯
por*_*ges 17
简答:是的:)
更长:
1)所有操作都是在flags变量的整数值上执行的,因此您可以根据这一点考虑它们.
2)是的.
3)要么有效.但是,值得注意的是,如果有人将无效值推入变量,则== TrainingComponentTypes.All版本将失败.例如:
var badValue = (TrainingComponentTypes)128 | TrainingComponentTypes.All;
// now badValue != TrainingComponentTypes.All
// but (badValue & TrainingComponentTypes.All) == TrainingComponentTypes.All
Run Code Online (Sandbox Code Playgroud)
对于这部分:
我不确定我们是否会收到一个值,其中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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,All只是|所有这些值的按位.您不能将任何其他TraningComponentTypes与All结合使用,因为All已经包含它们!此外,如果将它们与|自己组合在一起,它与直接使用All完全相同(因此,在枚举中定义它时,All只是一种方便).
4)您可以使用它来检查None或All,但不能检查其他值.
值得注意的是,Enum上有一种方便的方法可以为你做这些检查:Enum.HasFlag.
鉴于上面的例子,我对逻辑比较的理解是否正确?
是的,在这种情况下,逻辑意味着运营商的平等和不平等.
我执行按位比较的方式是否正确?
是的,但有一种更简单的方法:Enum.HasFlag.例如:
tct.HasFlag(TrainingComponentTypes.Qualification)
Run Code Online (Sandbox Code Playgroud)
代替:
(tct & TrainingComponentTypes.Qualification) == TrainingComponentTypes.Qualification
Run Code Online (Sandbox Code Playgroud)
处理"全部"值(按位或逻辑)的正确方法是什么.我不确定我们是否会收到一个值,其中All与其他TrainingComponentTypes结合使用.我不明白为什么会这样,但是,你永远都不知道?
我认为最好All将enum自身定义为其所有部分的按位OR.但是你会看到人们都是这样做的.
我是否正确地假设switch语句基本上不应该用于按位枚举(给定none似乎是特殊情况并且需要逻辑比较)?
一点都不.随意使用它们是switch陈述.该case值必须是常量,但他们可以表达和平等的测试.编译器会告诉你是否做了一些愚蠢的事情,比如尝试case两次使用相同的值.