对于enum中的None(0)值,HasFlags总是返回true



这是enum的定义:

[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

HasFlag实际上是这样的:

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

我以前也遇到过这种情况。这是在。net框架中的设计:

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

你可以在这里阅读更多关于这个的信息

已经有太多的答案描述了为什么会发生这种情况,所以我只是补充说,你可以做什么来得到你正在寻找的是不使用HasFlag在这种情况下,而是使用var hasNone = myAnimals == Animals.None

我个人真的很讨厌扩展方法,但是如果你真的希望能够只写myOptionEnum.HasNoFlags(),那么可以把它放在Enum的扩展中。在这种特殊情况下,我会显式检查None值。

那么Enum.HasFlags解析为如下内容:

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

对于0 -value-enum-field总是为真。

From MSDN

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

thisInstance And flag = flag

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

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

我最终删除了'None'元素。它是一个"魔法值",会干扰正确的标志枚举操作(如HasFlag())。

如果没有值,则使用Nullable,即Animals?(现在支持基本类型)

EDIT:我需要一个'Default'值(非零)用于可序列化对象,以避免使用Nullable(与业务逻辑冲突)。但我认为这仍然比使用'None=0'要好。

相关内容

  • 没有找到相关文章

最新更新