简体   繁体   English

.NET enum.HasFlag()错误?

[英].NET enum.HasFlag() bug?

I'm using the following .NET 4.5.2 code: 我正在使用以下.NET 4.5.2代码:

if (this.ContainsFocus && keyData == (Keys.Tab|Keys.Shift))
{ ... }

Why is the expression true when ContainsFocus (bool = true) and keyData (System.Windows.Forms.Keys) is Keys.O | 当ContainsFocus(bool = true)和keyData(System.Windows.Forms.Keys)为Keys.O时,为什么表达式为true? Keys.Shift? Keys.Shift?

As you can see the breakpoint is hit: 如您所见,断点被击中:

breakpointscreenshot

with this values: 具有以下值:

watchscreenshot

A workaround for this bug (?!) is: 该错误(?!)的解决方法是:

if (this.ContainsFocus && (int)keyData == (int)(Keys.Tab|Keys.Shift))
{ ... }

No, HasFlag does not have a bug. 不, HasFlag没有错误。 Unfortunately, the .NET FlagsAttribute is all or nothing and System.Windows.Forms.Keys is defined in such a way that only Keys.Modifiers may be used as flags. 不幸的是,.NET FlagsAttribute是全有或全无, System.Windows.Forms.Keys的定义方式是只能将Keys.Modifiers用作标志。

From https://msdn.microsoft.com/en-us/library/system.windows.forms.keys%28v=vs.110%29.aspx 来自https://msdn.microsoft.com/zh-cn/library/system.windows.forms.keys%28v=vs.110%29.aspx

The Keys class contains constants for processing keyboard input. Keys类包含用于处理键盘输入的常量。 The members of the Keys enumeration consist of a key code and a set of modifiers combined into a single integer value. Keys枚举的成员由一个键代码和一组修饰符组成,这些修饰符组合成一个整数值。 In the Win32 application programming interface (API) a key value has two halves, with the high-order bits containing the key code (which is the same as a Windows virtual key code), and the low-order bits representing key modifiers such as the SHIFT, CONTROL, and ALT keys. 在Win32应用程序编程接口(API)中,键值有两个部分,其中高阶位包含键码(与Windows虚拟键码相同),低位位代表键修饰符,例如SHIFT,CONTROL和ALT键。

As a result, you can check any of the modifiers ( Keys.Shift , Keys.Alt , Keys.Control ) with HasFlag , but nothing else. 其结果是,您可以检查任何修饰符(的Keys.ShiftKeys.AltKeys.Control )与HasFlag ,但没有别的。

This is not a bug of HasFlag , it is how it work. 这不是HasFlag的错误, HasFlag它的工作方式。
Suppose we have the following values: 假设我们具有以下值:

var a = (Keys.Tab | Keys.Shift);
var b = (Keys.O | Keys.Shift);

Now we analyze the bits of these values (when we cast them to integers): 现在,我们分析这些值的位(将它们转换为整数时):

a: 1000000000100 000 1 a:1000000000100 000 1
b: 1000000000100 111 1 b:1000000000100 111 1

If we call a.HasFlag(b) we get false because not every 1-bit from b is a 1 in a too. 如果我们调用a.HasFlag(b)我们得到false ,因为并不是每一个从B 1位是 1太大。 But if we call b.HasFlag(a) we get true because every 1-bit of a is set in b too. 但是,如果我们称之为b.HasFlag(a)我们得到true原因每1位为b设置得。

That's why you need to compare the values with a==b or with a.HasFlag(b) && b.HasFlag(a) . 这就是为什么您需要将值与a==ba.HasFlag(b) && b.HasFlag(a) Then it will work properly. 然后它将正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM