【问题标题】:.NET enum.HasFlag() bug?.NET enum.HasFlag() 错误?
【发布时间】:2015-08-05 14:37:38
【问题描述】:

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

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

为什么当 ContainsFocus (bool = true) 和 keyData (System.Windows.Forms.Keys) 为 Keys.O 时表达式为真Keys.Shift?

如你所见,断点被命中:

使用这个值:

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

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

【问题讨论】:

  • 你使用哪个控制事件?
  • Keys: "不要将此枚举中的值用于组合按位运算。枚举中的值不是互斥的。"
  • @AdamHouldsworth - 是的,我确实发现将 FlagsAttribute 应用于该枚举......很麻烦。

标签: c# .net enums flags enum-flags


【解决方案1】:

不,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),但不能检查其他任何修饰符。

【讨论】:

    【解决方案2】:

    这不是HasFlag 的错误,而是它的工作原理。
    假设我们有以下值:

    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 的每一位也都设置在b 中。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多