对于枚举中的None(0)值,HasFlags总是返回true
这是枚举定义:
[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 Framework中设计的:
如果flag的基础值为零,则该方法返回true。 如果不希望出现这种情况,可以使用Equals方法测试零的相等性,并仅在flag的基础值为非零时调用HasFlag,如下例所示。
您可以在MSDN文章中阅读更多相关内容: http : //msdn.microsoft.com/en-GB/library/system.enum.hasflag.aspx
已经有大量的答案描述了为什么会发生这种情况,所以我只想补充一点,你能做的就是在这种情况下不使用HasFlag
,而是做var hasNone = myAnimals == Animals.None
。
我个人真的厌恶扩展方法,但是如果你真的很重视只能编写myOptionEnum.HasNoFlags()
,就可以将它放在Enum
的扩展中。 我会在这种特殊情况下显式检查None
值。
好的Enum.HasFlags
解析如下:
var hasNone = (myAnimals & Animals.None) == Animals.None
对于零值枚举字段,这总是如此。
来自MSDN
HasFlag方法返回以下布尔表达式的结果。
thisInstance And flag = flag
这只是HasFlag
方法的已定义行为。 从MSDN文档
如果flag的基础值为零,则该方法返回true