2013-03-15 137 views
18

無(0)值爲true,這是枚舉定義:HasFlags始終返回枚舉

現在,考慮下面的代碼,爲什麼該值Animals.None的HasFlag方法的返回真的嗎?

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 

回答

19

HasFlag有效的是這樣的:

HasFlag = (GivenFlag & Value) == GivenFlag; 

//"Anything" AND 0 == 0 --> always true 
0

Enum.HasFlags解析爲類似如下:

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

一個零值,枚舉場這將永遠是正確的。

0

MSDN

的HasFlag方法返回以下布爾表達式的結果。

thisInstance And flag = flag 
0

這只是HasFlag方法的定義行爲。從MSDN文檔

如果標誌的基礎值是零,該方法返回true

6

我碰到這個自己之前。 它是在.NET Framework中設計的:

如果標誌的基礎值爲零,則該方法返回true。如果這種行爲不可取,那麼您可以使用Equals方法來測試是否等於零,並且只有在標記的基礎值非零時才調用HasFlag,如以下示例所示。

您可以在MSDN文章在這裏讀多一點關於這一點:http://msdn.microsoft.com/en-GB/library/system.enum.hasflag.aspx

2

已經有說明爲什麼出現這種情況的答案過多,所以我只想補充一點,你可以做什麼得到什麼你正在尋找的是在這種情況下不使用HasFlag,而是var hasNone = myAnimals == Animals.None

我個人確實不喜歡擴展方法,但是如果你真的有能力只寫myOptionEnum.HasNoFlags()就可以把它放在Enum的擴展名上。不過,我會在明確檢查None值的情況下運行。