如果语句在组合枚举值上没有按预期工作

时间:2015-11-19 04:33:15

标签: c# .net debugging if-statement

这是一个古怪的。

我有以下代码......

//MyClass.js
class MyClass {
   constructor(foo) {
     this.foo = foo
   }

   func(){/*ETC */}
 }

 module.exports = function(foo){
   return new MyObject(foo);
 }

当我运行此状态时,状态为//in app.js var myClass = require('./MyClass'); var mc = new myClass(foo); ,if语句似乎失败(不执行它所假设的)。

有趣的是,如果我调试并逐步执行代码并观察语句,它总是在我的调试器中返回foreach (IScanTicket ticket in this) { if (ticket.Status == TicketStatus.Created || ticket.Status == (TicketStatus.Transfered | TicketStatus.Created)) return ticket; } } ,但是当我单步执行代码时它无法进入块。

为什么调试器会显示该语句为Created|Transferred,但仍然继续这样做?它就像调试器告诉我的那样。

有没有人经历过这个?

P.S。我使用的是Xamarin studio 5.9.7

2 个答案:

答案 0 :(得分:3)

评论太长了:

实际上,[Flags]属性根本不会改变枚举的语义,它是ToString方法最常用来发出一系列名称而不是合并值的数字。

让我们说你的枚举是这样声明的(没有Flags属性):

enum TicketStatus
{
    Created = 1,
    Transferred = 2,
    Sold = 4
}

您仍然可以组合不同的成员并执行适用于Flags枚举的任何算法:

TicketStatus status = TicketStatus.Created | TicketStatus.Transferred;

但是,以下内容将打印3

Console.WriteLine(status);

但是,如果您添加[Flags]属性,则会打印Created, Transferred

另外,值得注意的是,TicketStatus.Created | TicketStatus.Transferred你真的对基础整数值做了一个按位OR,请注意我们的示例中指定的值是如何毫不含糊的可组合:

Created :    0001
Transferred: 0010
Sold:        0100

因此,3的值可以明确地确定为CreatedTransferred的组合。但是,如果我们有这个:

enum TicketStatus
{
    Created = 1,      // 0001
    Transferred = 2,  // 0010
    Sold = 3,         // 0011
}

正如二进制表示显而易见的那样,组合值和检查成员是有问题的,因为组合成员可能是模糊的。例如什么是status

status = TicketStatus.Created | TicketStatus.Transferred;

Created, Transferred还是真的Sold?但是,如果你尝试这样做,编译器就不会抱怨,这可能导致很难找到像你这样的错误,其中一些检查没有按照你的预期工作,所以它会对你有所帮助。确保定义对于按位混合和比较是合理的。

在相关的说明中,由于您的if声明实际上只是检查故障单是否具有Created状态,无论是否与其他成员合并,这里有更好的方法来检查(.NET> = 4):

status.HasFlag(TicketStatus.Created)

或(.NET< 4):

(status & TicketStatus.Created) != 0

至于为什么你的枚举没有按预期工作,几乎可以肯定是因为你没有明确地为其成员明确指定可按位的可组合值(通常为2的幂)。

答案 1 :(得分:0)

感谢@MarcinJuraszek和@YeldarKurmangaliyev。

根据我原先的想法,似乎在枚举上设置了[Flags]属性 。现在添加此属性可使enum以任意组合工作。

所以似乎没有这个属性会影响连接枚举值的顺序。