问题
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).
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.
回答1:
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");
}
Behind the scenes of this is explained by numerous others. Can personally recommend Alan Zucconi's Enum, Flags and bitwise operators
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 &
.
回答2:
Here's what you need:
if ((resistances & abilityType) != 0)
{
print("You are resistance to this damage type");
}
...
来源:https://stackoverflow.com/questions/56621287/check-if-an-enum-flag-contains-a-certain-flag-value