检查枚举标志是否包含某个标志值 [英] Check if an enum flag contains a certain flag value

查看:82
本文介绍了检查枚举标志是否包含某个标志值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C# 中(使用 Unity 处理游戏)我有一个带有 [Flag] 属性的枚举.我已经实例化了两次.我想要一种比较两个枚举的方法.特别是如果 enum A(将有多个标志)包含来自 enum B 的标志(它只会被分配一个标志).

In C# (using Unity working on a game) I have an enum with the [Flag] attribute. I have instantiated it twice. I would like a way to compare the two enums. Specifically if enum A (which will have multiple flags) contains a flag from enum B (which will only ever be assigned a single flag).

不是试图将单个实例化的枚举与单个标志进行比较(这已被多次回答).

I am not trying to compare a single instantiated enum to a single flag (this has been answered multiple times).

我怀疑我可以通过使用 GetValue 转储值并在 foreach 循环中比较这些值来做到这一点,但似乎应该有更直接的比较方法.

I suspect I could do this by dumping values with GetValue and comparing those values on a foreach loop, but it seems like there should be a more direct way to compare.

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
        }
    }
}

我想要上面的代码来检查阻力是否包含来自能力类型的标志.在上面的例子中,有问题的攻击将传入它的能力类型.如果类型是水或穿刺,它应该打印阻力声明.如果是其他类型,应该会正常造成伤害.

I'd like the above code to check if resistances contains the flag from abilityType. In the example above, the attack in question will pass it's abilityType in. If that type is water or pierce, it should print the resistance statement. If it's another type, it should deal damage as normal.

推荐答案

正如评论和其他答案中所述,您想要滥用的是按位 & 运算符以作为枚举进行比较是 (默认) 基于 int 类型.但是,从 .NET 4.0 开始,添加了 Enum.HasFlag 扩展方法正是这样做的并提高了可读性.

What you want is to abuse, as stated in the comments and other answers, is the bitwise & operator to compare as enums are (by default) based on the int type. However since .NET 4.0 there has been the addition of Enum.HasFlag extension method that does exactly this and increases readability.

// 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");
}

在这背后有许多其他人解释.可以个人推荐Alan Zucconi的Enum, Flags and bitwise operators

Behind the scenes of this is explained by numerous others. Can personally recommend Alan Zucconi's Enum, Flags and bitwise operators

简短版本是按位 AND (&) 运算符给出两个值匹配"的结果,因为它们都处于活动状态,一点一点.将其视为选择性过滤器的一种方式.要检查未知标志集的值 A 是否包含特定标志 B,请使用仅允许标志 B 通过的过滤器并检查是否有任何东西通过,其中任何东西都表示为除零以外的任何东西.过滤器与您要查找的标志完全相同.因此表达式变为 (A & B) != 0.括号强制覆盖操作顺序,因为 !=& 具有更高的优先级.

Short version is that the bitwise AND (&) operator gives a result of where two values "match" in the sense that they're both active, bit by bit. One way to think of it is as a selective filter. To check if a value A of unknown flag set contains a specific flag B, you use the filter which only allows flag B to pass through and check if anything got through, where anything is represented as anything else than zero. The filter is simply the same as the flag you wish to look for. Therefore the expression becomes (A & B) != 0. Parentheses to force override order of operations since != has higher precedence than &.

这篇关于检查枚举标志是否包含某个标志值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆