Проверьте, содержит ли флаг перечисления определенное значение флага - PullRequest
0 голосов
/ 16 июня 2019

В C # (используя Unity, работающую над игрой) у меня есть enum с атрибутом [Flag].Я создал его дважды.Я хотел бы сравнить два перечисления.В частности, если enum A (который будет иметь несколько флагов) содержит флаг из enum B (который будет когда-либо назначен только один флаг).

Я не , пытаясь сравнитьединственное экземплярное перечисление к одному флагу (на это отвечали несколько раз).

Я подозреваю, что я мог бы сделать это, выгрузив значения с помощью GetValue и сравнив эти значения в цикле foreach, но похожеДолжен быть более прямой способ сравнения.

public enum AbilityType
{
    None = 0,
    Pierce = 1<<1,
    Blunt = 1<<2,
    Slash = 1<<3,
    Water = 1<<4,
    // etc.
};


public class Ability : MonoBehaviour
{
    public AbilityType abilityType;
}

public class AbilitiedObject : StatisticalObject
{
    public AbilityType resistances;

    protected override void Awake()
    {
        base.Awake();
        resistances = AbilityType.Pierce | AbilityType.Water;
    }

    public void TakeDamage(int damageAmount, AbilityType abilityType)
    {
        if( ) // Check if resistances contains abilityType's flag here
        {
            print("You are resistance to this damage type");
        }
        else
        {
            // Player takes damage
        }
    }
}

Я бы хотел, чтобы приведенный выше код проверял, содержит ли сопротивление флаг изilityType.В приведенном выше примере рассматриваемая атака передаст свойabilityType. Если это тип water или pierce, он должен напечатать выражение сопротивления.Если это другой тип, он должен наносить урон как обычно.

Ответы [ 2 ]

2 голосов
/ 16 июня 2019

Вы хотите злоупотреблять, как указано в комментариях и других ответах, побитовым оператором & для сравнения, поскольку перечисления имеют значение (по умолчанию) на основе типа int.Однако начиная с .NET 4.0 был добавлен метод расширения Enum.HasFlag, который делает именно это и повышает удобочитаемость.

// These two are semantically equal

if (resistance.HasFlag(abilityType))
{
    print("You are resistance to this damage type");
}

if ((resistance & abilityType) != 0)
{
    print("You are resistance to this damage type");
}

За кулисами этого объясняется множество других.Можно лично порекомендовать Enum, Flags и побитовые операторы Алана Цуккони

Короткая версия заключается в том, что побитовый оператор AND (&) дает результат, когда два значения "совпадают" в том смысле, чтоони оба активны, по крупицам.Один из способов думать об этом - это выборочный фильтр.Чтобы проверить, содержит ли значение A неизвестного набора флагов определенный флаг B, вы используете фильтр, который позволяет только флагу B проходить и проверять, прошел ли что-нибудь, где что-либо представлено как что-либо кроме нуля,Фильтр просто совпадает с флагом, который вы хотите найти.Поэтому выражение становится (A & B) != 0.Скобки для принудительного переопределения порядка операций, поскольку != имеет более высокий приоритет, чем &.

2 голосов
/ 16 июня 2019

Вот что вам нужно:

if ((resistances & abilityType) != 0)
{
    print("You are resistance to this damage type");
}
...
...