Почему не работает метод HasFlags()?

Есть перечисление с флагами.

[Flags]
public enum Allergens
{
    Egg = 1,
    Peanut = 2,
    Shellfis = 4,
    Strawberrie = 8,
    Tomatoe = 16,
    Chocolat = 32,
    Polle = 64,
    Cat = 128,
}

Нужно реализовать методы

public class Allergies
{
    public int score;

    public Allergies(int score)
    {
        this.score = score;
    }

    public bool IsAllergicTo(Allergens allergens)
    {            
        var all = Allergens.All;

        bool result = all.HasFlag(allergens);

        return result;
    }
    
    public Allergens[] AllergensList()
    {           
        
    }
}

Это все, что я смог понять с этими битовыми флагами. Нутром чувствую, что здесь решается все просто, но знаний пока не хватает. Буду благодарен за любую помощь. Спасибо.


Ответы (1 шт):

Автор решения: IOException

Я правильно понимаю, что нужно проверить, имеет ли указанный человек реакцию на указанную аллергию? При этом список тех аллергенов, на которые он реагирует, указан в поле score (кстати, советую свойства и поля с большой буквы называть, по правилам языка так лучше)? В такой ситуации не должна быть проверка на соответствие любому из флагов. Если у вас указано all.HasFlag, то оно всегда будет возвращать true, т.к. любая комбинация обязательно будет встречаться в вашем all. При указании флагов числовое значение перечислений складывается, так Allergens.Eggs | Allergens.Chocolate будет иметь значение 32+1, то есть 33. В битовом представлении это будет выглядеть как 0b00010001. HasFlag проверяет как раз эти значения бит. Соответственно, если список "нужных" аллергенов указан в score, то код для проверки будет выглядеть примерно так:

public bool IsAllergicTo(Allergens allergens)
{
    var test = (Allergens)score;

    bool result = test.HasFlag(allergens);

    return result;
}

Также у вас снизу был недоделанный метод, в котором нужно вернуть массив всех аллергенов. Для проверки нужно проверить наличие непосредственно каждого аллергена по отдельности, и, если он есть, то добавить в массив. Хотя, так как они у вас помечены [Flags], было бы проще просто вернуть результат с флагами. При переводе в строку оно вроде в любом случае список всех выведет.

public Allergens[] AllergensList()
{
    List<Allergens> ret = new List<Allergens>();
    for (int i = 1; i < 129; i*=2)
    {
        if (IsAllergicTo((Allergens)i)) ret.Add((Allergens)i);
    }
    return ret.ToArray();
}
→ Ссылка