Подтвердить что ты не робот

HasFlags всегда возвращает true для значения None (0) в перечислении

Это определение перечисления:

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

Теперь, учитывая следующий код, почему метод HasFlag возвращает true для значения Animals.None?

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
4b9b3361

Ответ 1

HasFlag эффективно это:

HasFlag = (GivenFlag & Value) == GivenFlag;

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

Ответ 2

Я столкнулся с этим перед собой. Он по дизайну в .NET Framework:

Если базовое значение флага равно нулю, метод возвращает true. Если это поведение нежелательно, вы можете использовать метод Equals для проверки равенства с нулем и вызывать HasFlag только в том случае, если базовое значение флага не равно нулю, как показано в следующем примере.

Вы можете прочитать немного больше об этом в статье MSDN здесь: http://msdn.microsoft.com/en-GB/library/system.enum.hasflag.aspx

Ответ 3

Уже есть множество ответов, описывающих ПОЧЕМУ это происходит, поэтому я просто добавлю, что то, что вы можете сделать, чтобы получить то, что вы ищете, - это не использовать HasFlag в этом случае, а вместо этого var hasNone = myAnimals == Animals.None,

Я лично очень ненавижу методы расширения, но можно было бы разместить это в расширении на Enum, если вы действительно цените возможность писать myOptionEnum.HasNoFlags(). Я просто запускал бы с явной проверкой значения None в этом специальном случае.

Ответ 4

Ну Enum.HasFlags разрешается как-то вроде следующего:

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

Это всегда будет верно для поля с нулевым значением-enum.

Ответ 5

От MSDN

Метод HasFlag возвращает результат следующего булевого выражения.

thisInstance And flag = flag

Ответ 6

Это всего лишь определенное поведение метода HasFlag. Из MSDN документация

если базовое значение флага равно нулю, метод возвращает true