Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# If语句在组合枚举值上未按预期工作_C#_.net_Debugging_If Statement - Fatal编程技术网

C# If语句在组合枚举值上未按预期工作

C# If语句在组合枚举值上未按预期工作,c#,.net,debugging,if-statement,C#,.net,Debugging,If Statement,这是一个奇怪的问题 我有以下代码 foreach (IScanTicket ticket in this) { if (ticket.Status == TicketStatus.Created || ticket.Status == (TicketStatus.Transfered | TicketStatus.Created)) return ticket; } } 当我运行这个程序时,状态为Created | transfered,if语句似乎失败了(而不

这是一个奇怪的问题

我有以下代码

foreach (IScanTicket ticket in this) {
    if (ticket.Status == TicketStatus.Created || ticket.Status == (TicketStatus.Transfered | TicketStatus.Created))
        return ticket;
    }
}
当我运行这个程序时,状态为
Created | transfered
,if语句似乎失败了(而不是执行它应该做的)

有趣的是,如果我调试并单步执行代码并观察语句,它总是在我的调试器中返回
TRUE
,但当我单步执行代码时,它无法进入块

为什么调试器会显示该语句是
true
,但却像它不是那样继续?这就像调试器告诉我的谎言一样

有人经历过这种情况吗


另外,感谢@MarcinJuraszek和@YeldarKurmangaliyev,我正在使用Xamarin studio 5.9.7

似乎
[Flags]
属性没有像我最初认为的那样在枚举上设置。添加此属性现在可以使枚举在任意组合中工作


因此,似乎没有此属性会影响连接的枚举值的顺序。

注释过长:

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

假设您的枚举是这样声明的(没有
Flags
属性):

您仍然可以组合不同的成员,并执行适用于标志枚举的任何算术运算:

TicketStatus status = TicketStatus.Created | TicketStatus.Transferred;
但是,以下内容将打印
3

Console.WriteLine(status);
但是如果您添加
[Flags]
属性,它将打印
创建、传输的

另外,需要注意的是,通过
TicketStatus.Created | TicketStatus.transfer
您实际上是在对基础整数值执行按位
操作,请注意在我们的示例中,赋值是如何明确组合的:

Created :    0001
Transferred: 0010
Sold:        0100
因此,
3
的值可以明确地确定为创建的
和传输的
的组合。但是,如果我们有这个:

enum TicketStatus
{
    Created = 1,      // 0001
    Transferred = 2,  // 0010
    Sold = 3,         // 0011
}
从二进制表示中可以明显看出,组合值和检查成员是有问题的,因为组合的成员可能是不明确的。e、 g.这里的
状态是什么

status = TicketStatus.Created | TicketStatus.Transferred;
它是创建的、转移的还是真正售出的?但是,如果您尝试这样做,编译器不会抱怨,这可能会导致很难跟踪像您这样的错误,其中一些检查没有按照您预期的方式工作,因此您需要确保定义对于按位混合和比较是合理的

另一方面,由于您的
if
语句实际上只是检查票证是否具有
已创建的
状态,而不管是否与其他成员组合,因此这里有一个更好的检查方法(.NET>=4):


或者(.NET
TicketStatus
如何?这是一个具有
[Flags]
属性的枚举吗?当它失败时,
ticket.Status
的值是多少,但您希望它是否为
true
?很有趣……如果我交换枚举联接(例如
(TicketStatus.Created | TicketStatus.Transfered)
)这似乎是可行的。由于枚举是一个基于
字节的
标记枚举,我本以为它不会有什么不同。有什么想法吗?@GuyPark你能不能也显示
TicketStatus
的代码?请尝试清理解决方案并重建它,有时可能是由于bin文件夹中存在旧文件而发生的解决方案的r(bin文件夹可能与xamarin解决方案不同)。没有硬编码值的枚举会自动编号。使用标志枚举时,最好明确定义值。例如,0、0x1、0x2、0x4、0x8、0x16、0x32、0x64..等等,如果硬编码值,则无论是否有[标志]都可以工作不需要对它们进行硬编码,因为如果在现有值中间添加一个新值,它将抵消旧值,这些值会使数据(例如在数据库中)出现问题。如果你在数据库中存储枚举值,对它们进行硬编码总是一个好主意。如果你不这样做,就没有理由这样做。我总是对它们进行硬编码,以防编译器不这样做。从技术上讲,我的代码是对的,但实际上编译器是正确的为其他内容添加墨迹。我只是想把这归因于编译器和陷阱中的一个怪癖,以防出现。我可以解释为什么在这一点上,但当我添加了
[flags]
属性时,它开始按预期运行。就像@Saeb Amini提到的,使用.hasglag()可能会更好方法,但作为旧的C++,我通常会回到按位编码的根源。绝对地,这就是我理解它的原因,这就是为什么它混淆了为什么它不工作。从技术上讲,您是正确的,但我发现实际运行时并非如此,直到我添加了
[flags]
属性。这就是问题所在。当调试器向我提供您提到的内容时,了解编译器/JIT的想法会很有趣。
status = TicketStatus.Created | TicketStatus.Transferred;
status.HasFlag(TicketStatus.Created)
(status & TicketStatus.Created) != 0