【问题标题】:HasFlags always returns true for None (0) value in enumHasFlags 对于枚举中的 None (0) 值总是返回 true
【发布时间】:2013-03-15 15:48:39
【问题描述】:

这是枚举定义:

[Flags]
enum Animals
{
    None = 0,
    Dog = 1,
    Cat = 2,
    Horse = 4,
    Zebra = 8,
}

现在,给定以下代码,为什么 HasFlag 方法对 Animals.None 值返回 true?

Animals myAnimals = Animals.Dog | Animals.Horse;

var hasNone = myAnimals.HasFlag(Animals.None);    //true! Why?
var hasCat = myAnimals.HasFlag(Animals.Cat);      //false
var hasDog = myAnimals.HasFlag(Animals.Dog);      //true
var hasHorse = myAnimals.HasFlag(Animals.Horse);  //true
var hasZebra = myAnimals.HasFlag(Animals.Zebra);  //false

【问题讨论】:

    标签: c# enums enum-flags


    【解决方案1】:

    HasFlag 实际上是这样的:

    HasFlag = (GivenFlag & Value) == GivenFlag;
    
    //"Anything" AND 0 == 0  --> always true
    

    【讨论】:

      【解决方案2】:

      我自己就遇到过这个问题。 这是 .NET Framework 中的设计:

      如果 flag 的基础值为零,则该方法返回 true。如果这种行为不可取,您可以使用 Equals 方法测试是否与零相等,并仅在 flag 的基础值非零时调用 HasFlag,如下例所示。

      您可以在此处的 MSDN 文章中阅读更多相关信息:http://msdn.microsoft.com/en-GB/library/system.enum.hasflag.aspx

      【讨论】:

        【解决方案3】:

        已经有很多答案描述了为什么会发生这种情况,所以我只想补充一点,在这种情况下,你可以做的是不使用HasFlag,而是使用var hasNone = myAnimals == Animals.None .

        我个人非常讨厌扩展方法,但如果你真的很重视能够只写myOptionEnum.HasNoFlags(),可以将它放在Enum 的扩展中。不过,在这种特殊情况下,我会明确检查 None 的值。

        【讨论】:

          【解决方案4】:

          Enum.HasFlags 解析为类似以下内容:

          var hasNone = (myAnimals & Animals.None) == Animals.None
          

          对于零值枚举字段,这始终是正确的。

          【讨论】:

            【解决方案5】:

            来自MSDN

            HasFlag 方法返回以下布尔表达式的结果。

            thisInstance And flag = flag
            

            【讨论】:

              【解决方案6】:

              这只是HasFlag 方法的定义行为。来自MSDN 文档

              如果 flag 的基础值为零,则该方法返回 true

              【讨论】:

                【解决方案7】:

                我最终删除了“无”元素。它是一个“神奇值”,会干扰正确的 Flags Enum 操作(如 HasFlag())。

                如果没有价值,那么使用 Nullable 即动物? (现在支持原始类型)

                编辑:我需要在可序列化对象中使用“默认”值(非零)以避免使用 Nullable(与业务逻辑冲突)。但我认为这仍然比使用 'None=0' 更好。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-03-21
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多