C# .NET enum.HasFlag()错误?

C# .NET enum.HasFlag()错误?,c#,.net,enums,flags,enum-flags,C#,.net,Enums,Flags,Enum Flags,我正在使用以下.NET 4.5.2代码: if (this.ContainsFocus && keyData == (Keys.Tab|Keys.Shift)) { ... } 当包含cus(bool=true)和keyData(System.Windows.Forms.Keys)为Keys.O | Keys.Shift时,为什么表达式为true 如您所见,断点被命中: 使用此值: 此错误(?!)的解决方法是: 这不是HasFlag的bug,而是它的工作方式。 假设我们有以

我正在使用以下.NET 4.5.2代码:

if (this.ContainsFocus && keyData == (Keys.Tab|Keys.Shift))
{ ... }
当包含cus(bool=true)和keyData(System.Windows.Forms.Keys)为Keys.O | Keys.Shift时,为什么表达式为true

如您所见,断点被命中:

使用此值:

此错误(?!)的解决方法是:


这不是HasFlag的bug,而是它的工作方式。
假设我们有以下值:

var a = (Keys.Tab | Keys.Shift);
var b = (Keys.O | Keys.Shift);
现在我们分析这些值的位(当我们将它们转换为整数时):

a:100000000000000001
b:10000000001001111

如果我们调用
a.hasvag(b)
我们得到
false
,因为b中的每一个1位也不是a中的1。但是如果我们调用
b.hasvag(a)
我们会得到
true
,因为a的每1位也是在b中设置的


这就是为什么您需要将值与
a==b
a.hasvag(b)和&b.hasvag(a)
进行比较。然后它就会正常工作。

不,
hasblag
没有bug。不幸的是,.NET
FlagsAttribute
是all或nothing,并且
System.Windows.Forms.Keys
的定义方式只能将
Keys.Modifiers
用作标志

Keys类包含用于处理键盘输入的常量。这个 键枚举的成员由一个键代码和一组 组合为单个整数值的修饰符。在Win32中 应用程序编程接口(API)一个键值有两半, 具有包含密钥代码的高阶位(与 Windows虚拟密钥代码)和表示密钥的低位 修改器,例如SHIFT、CONTROL和ALT键


因此,您可以使用
HasFlag
检查任何修饰符(
Keys.Shift
Keys.Alt
Keys.Control
),而不检查其他任何修饰符

您使用哪个控件事件?:“不要将此枚举中的值用于组合的按位操作。枚举中的值不是互斥的。”@Damien_不信者忽略顶部附近的行:
此枚举具有允许其成员值按位组合的FlagsAttribute属性。
lol应用
FlagsAttribute
可能导致自动文档失败。@Adamhuldsworth-是,我确实发现
FlagsAttribute
对该枚举的应用。。。麻烦的
var a = (Keys.Tab | Keys.Shift);
var b = (Keys.O | Keys.Shift);