标志enum位运算符未按预期工作

本文关键字:工作 enum 运算符 标志 | 更新日期: 2023-09-27 18:09:36

我在Windows mobile 6.5上使用c# 3.5编写移动应用程序,我一直在使用这个简单的代码,但它突然停止工作:

//Regroup the issues
ScanIssuesEnum NewIssues = 0;
NewIssues |= Direction1Issues;
NewIssues |= Direction2Issues;
//Remove invalid directions because we don't care about them in bidirectionnal mode
NewIssues ^= ScanIssuesEnum.InvalidDirectionIssue;
return NewIssues;

我彻底检查了我所有的类型,只是为了确保我没有使用另一种类型,一切都是基于相同的ScanIssuesEnum类型和类型是[Flag]'ed,你可以看到下面:

[Flags] public enum ScanIssuesEnum
{
    TicketUsedTooSoonIssue = 1,
    TicketUsedTooLateIssue = 2,
    TicketUsageBustedIssue = 4,
    InvalidTripIssue = 8,
    InvalidDirectionIssue = 16,
    StartStopTooSoonIssue = 32,
    StartStopNotFoundIssue = 64,
    EndStopTooLateIssue = 128,
    EndStopNotFoundIssue = 256,
    MultipleUsageSameTripIssue = 512,
    MultipleUsageInFewHoursIssue = 1024,
    StudentTicketIssue = 2048,
    ConnectingTripWithinTimeframeFlag = 4096,
    UDESStudentTicketIssue = 8192,
}

在我目前的问题中,我可以在两个方向问题中看到EndStopNotFoundIssue,当组合成NewIssues时,我得到一个包含两次EndStopNotFoundIssue的值。我认为它不会真正重要,直到我返回值,也许这只是一个可视化的IDE错误,但没有,问题仍然存在。更糟糕的是,当我碰到删除InvalidDirectionIssue标志的行时,它将其添加到NewIssues…

我疯了吗?^=等于x = x ^ y,不是吗?所以我应该把旗子去掉,而不是加上去,对吧?

感谢

编辑#1 - DirectionIssues的值

根据Wonko的要求,Direction1Issue和Direction2Issue的值都是EndStopNotFoundIssue或256。

在"NewIssues ^= scanissuesenumo .InvalidDirectionIssue;"行之后,我的NewIssues由"EndStopNotFoundIssue | EndStopNotFoundIssue | InvalidDirectionIssue"组成。显然不应该这样!

编辑#2 - DirectionIssues的值被错误读取

哈,两个DirectionIssues有不同的值,我只是读错了。实际上是endstopnotfounissue和EndStopTooLateIssue。该死的脑子没读完整个单词呵呵。所以手术室的部分还好,是我的大脑在跟我开玩笑。

我改变了关于InvalidDirectionIssue的问题部分,我试图使用"x = x &~y"的形式,它工作,不知道为什么它工作,而"x ^= y",但地狱!解决方案发现!

标志enum位运算符未按预期工作

有几件事可能对你有帮助。

  • ^是异或的,所以它切换/切换你应用的位,它不清除它们。因此,如果EndStopNotFoundIssue值未设置,则使用^将设置它,而不是清除它。如果你想清除一个值,使用x &= ~y(与x与y的反转位)

  • EndStopNotFoundIssue | EndStopNotFoundIssue = EndStopNotFoundIssue。将一个值与自身进行交互只会返回相同的值。所以你有事瞒着我们。你用的是+而不是|之类的吗?你所访问的变量的值真的和你想的一样吗?您是否在调试器中单步执行代码以查看每个阶段的值?

  • 你需要发布更多的代码,让我们找出哪里出错了。
  • 您正在使用的值似乎不是来自您的enum(例如0和Direction1Issues)。所以我们不能读你的代码来找出什么可能会出错,因为我们不知道什么Direction1Issues被设置为。把不同的类型混在一起通常不是一个好主意。0是一个整数,但将其设置为枚举类型。定义一个像None=0这样的常量,使你的代码更容易读,更安全。

  • 对于你的常量,尝试使用下面的样式-它更容易看到你正在设置的位,知道你只设置了一个位,并确保你在添加新项时正确计算下一个值:

    public enum ScanIssuesEnum
    {
        TicketUsedTooSoonIssue = 1<<0,
        TicketUsedTooLateIssue = 1<<1,
        TicketUsageBustedIssue = 1<<2,
        InvalidTripIssue       = 1<<3,
        InvalidDirectionIssue  = 1<<4,
        ...
    

x ^= y相当于x = x ^ y。这意味着它切换y在标志枚举中的存在状态。可用于设置或取消设置