.NET的enum.HasFlag()有bug吗?

3
我将使用以下的.NET 4.5.2代码:
if (this.ContainsFocus && keyData == (Keys.Tab|Keys.Shift))
{ ... }

当ContainsFocus (bool = true)和keyData (System.Windows.Forms.Keys)为Keys.O | Keys.Shift时,表达式为真。
如您所见,断点被触发:
这些是值:
这个bug的解决方法(?!)是:
if (this.ContainsFocus && (int)keyData == (int)(Keys.Tab|Keys.Shift))
{ ... }

你会使用哪个控件事件? - Fredou
6
请勿将此枚举中的值用于位运算组合。该枚举中的值不是互斥的。 - Damien_The_Unbeliever
@Damien_The_Unbeliever 忽略顶部附近的那行:此枚举具有FlagsAttribute属性,允许对其成员值进行按位组合。哈哈,可能是自动文档生成器应用了FlagsAttribute导致的失败。 - Adam Houldsworth
@AdamHouldsworth - 是的,我确实觉得将FlagsAttribute应用于该枚举...令人困扰。 - Damien_The_Unbeliever
2个回答

4
不,HasFlag 没有错误。不幸的是,.NET FlagsAttribute 是全有或全无的,而且 System.Windows.Forms.Keys 的定义方式只允许使用 Keys.Modifiers 作为标志。
来自 https://msdn.microsoft.com/en-us/library/system.windows.forms.keys%28v=vs.110%29.aspx

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

因此,您可以使用 HasFlag 检查任何修饰符 (Keys.ShiftKeys.AltKeys.Control),但不能检查其他内容。

1
这不是HasFlag的bug,而是它的工作方式。
假设我们有以下数值:
var a = (Keys.Tab | Keys.Shift);
var b = (Keys.O | Keys.Shift);

现在我们分析这些值的位(当将它们转换为整数时):
a: 10000000001000001 b: 10000000001001111
如果我们调用 a.HasFlag(b),我们会得到 false,因为不是b中的每个1位也在a中为1。但是,如果我们调用b.HasFlag(a),我们会得到true,因为a的每个1位也被设置在了b中。
这就是为什么你需要使用 a==b 或者 a.HasFlag(b) && b.HasFlag(a) 来比较这些值,这样才能正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接