检查枚举标志是否包含特定标志值
Check if an enum flag contains a certain flag value
在 C# 中(使用 Unity 开发游戏)我有一个带有 [Flag] 属性的枚举。我已经实例化了两次。我想要一种方法来比较这两个枚举。特别是如果枚举 A(将有多个标志)包含一个来自枚举 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
}
}
}
我想用上面的代码检查 resistances 是否包含来自 abilityType 的标志。在上面的示例中,有问题的攻击将传递它的能力类型。如果该类型是水或刺穿,它应该打印抵抗声明。如果是另一种类型,它应该会造成正常伤害。
这是您需要的:
if ((resistances & abilityType) != 0)
{
print("You are resistance to this damage type");
}
...
正如评论和其他答案中所述,您想要的是滥用按位 &
运算符进行比较,因为枚举是 (by default) based on the int
type. However since .NET 4.0 there has been the addition of 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");
}
很多人都在幕后解释了这一点。可以个人推荐Alan Zucconi's Enum, Flags and bitwise operators
简而言之,按位与 (&
) 运算符给出了两个值 "match" 的结果,因为它们都处于活动状态,一点一点。一种将其视为选择性过滤器的方法。要检查未知标志集的值 A
是否包含特定标志 B
,您可以使用只允许标志 B
通过的过滤器,并检查是否有任何东西通过,什么东西是表示为除零以外的任何值。过滤器与您要查找的标志完全相同。因此表达式变为 (A & B) != 0
。括号强制覆盖操作顺序,因为 !=
的优先级高于 &
.
在 C# 中(使用 Unity 开发游戏)我有一个带有 [Flag] 属性的枚举。我已经实例化了两次。我想要一种方法来比较这两个枚举。特别是如果枚举 A(将有多个标志)包含一个来自枚举 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
}
}
}
我想用上面的代码检查 resistances 是否包含来自 abilityType 的标志。在上面的示例中,有问题的攻击将传递它的能力类型。如果该类型是水或刺穿,它应该打印抵抗声明。如果是另一种类型,它应该会造成正常伤害。
这是您需要的:
if ((resistances & abilityType) != 0)
{
print("You are resistance to this damage type");
}
...
正如评论和其他答案中所述,您想要的是滥用按位 &
运算符进行比较,因为枚举是 (by default) based on the int
type. However since .NET 4.0 there has been the addition of 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");
}
很多人都在幕后解释了这一点。可以个人推荐Alan Zucconi's Enum, Flags and bitwise operators
简而言之,按位与 (&
) 运算符给出了两个值 "match" 的结果,因为它们都处于活动状态,一点一点。一种将其视为选择性过滤器的方法。要检查未知标志集的值 A
是否包含特定标志 B
,您可以使用只允许标志 B
通过的过滤器,并检查是否有任何东西通过,什么东西是表示为除零以外的任何值。过滤器与您要查找的标志完全相同。因此表达式变为 (A & B) != 0
。括号强制覆盖操作顺序,因为 !=
的优先级高于 &
.