How to Check If Any Flags of a Flag Combination Are Set

How to check if any flags of a flag combination are set?

If you want to know if letter has any of the letters in AB you must use the AND & operator. Something like:

if ((letter & Letters.AB) != 0)
{
// Some flag (A,B or both) is enabled
}
else
{
// None of them are enabled
}

Check if an enum flag contains a certain flag value

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 &.

Check if flag contains any value of other flag

As per this answer (How to convert from System.Enum to base integer?)

You will need to wrap this code with an exception handler or otherwise ensure that both enums hold an integer.

public static class FlagExt
{
public static bool HasAny(this Enum me, Enum other)
{
return (Convert.ToInt32(me) & Convert.ToInt32(other)) != 0;
}
}

Check if an enum contains more than one flag

I am trying to check if an "enum instance" contains more than one flag.
I do not care which Flags the "instance" contains, I just want to know if there are more than one

Additionally I really don't wanna use something like the following:

 var state = Foo.Bar | Foo.Far;
Console.WriteLine(state.ToString().Count(x => x == ',') > 0); // True

There are more than a few different ways to accomplish what you want, I propose to do a bit (bitwise) check:

 public static bool MoreThanOneFlag<TValue>(TValue flag) where TValue : Enum => (Convert.ToInt32(flag) & (Convert.ToInt32(flag) - 1)) != 0;

In the above code block, we check if flag is not a power of two by checking using flag & (flag-1)) != 0 (the & operator) which computes the bitwise logical AND of its operands. If there's only one flag set, we assume then that the value would be a power of two, otherwise it's a non power of two.

Or, if you don't want a helper function just perform that check anywhere:

 bool value = (multiState & (multiState -1)) != 0;

For more information about bitwise, please check out more here.

References :

Bitwise and shift operators (C# reference)

Flags Enum.HasFlag not Working as Expected for Multiple bit fields

I suggest that you eschew HasFlag and just do it directly using bit operations:

var myFilteredListMultiple = MyMainList.Where(w => (w.FlagValue & (MyFlaggedEnum.First | MyFlaggedEnum.Fourth)) != 0);

Or if you have a set of bitflags passed in called, say, mask:

var myFilteredListMultiple = MyMainList.Where(w => (w.FlagValue & mask) != 0);

How to use flags to check if something from the collection matches the flag

You could try this solution:

var selectedAll = examples.Where(C => (C.FlagId & (int)FlagsTypes.All) == (int)C.FlagId).ToList();

Best practice to determine the amount of flags contained in a Enum-flag combination?

Option A:

public int FlagCount(System.Enum sender)
{
bool hasFlagAttribute = sender.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
if (!hasFlagAttribute) // No flag attribute. This is a single value.
return 1;

var resultString = Convert.ToString(Convert.ToInt32(sender), 2);
var count = resultString.Count(b=> b == '1');//each "1" represents an enum flag.
return count;
}

Explanation:

  • If the enum does not have a "Flags attribute", then it is bound to be a single value.
  • If the enum has the "Flags attribute", Convert it to the bit representation and count the "1"s. each "1" represents an enum flag.

Option B:

  1. Get all flaged items.
  2. Count them...

The code:

public int FlagCount(this System.Enum sender)
{
return sender.GetFlaggedValues().Count;
}

/// <summary>
/// All of the values of enumeration that are represented by specified value.
/// If it is not a flag, the value will be the only value returned
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static List<Enum> GetFlaggedValues(this Enum value)
{
//checking if this string is a flagged Enum
Type enumType = value.GetType();
object[] attributes = enumType.GetCustomAttributes(true);

bool hasFlags = enumType.GetCustomAttributes(true).Any(attr => attr is System.FlagsAttribute);
//If it is a flag, add all flagged values
List<Enum> values = new List<Enum>();
if (hasFlags)
{
Array allValues = Enum.GetValues(enumType);
foreach (Enum currValue in allValues)
{
if (value.HasFlag(currValue))
{
values.Add(currValue);
}
}
}
else//if not just add current value
{
values.Add(value);
}
return values;
}

Is there a way to tell if an enum has exactly one, multiple or no flags set?

you can use this code :

var item = Orientation.North | Orientation.South;
int i = 0;
foreach (Orientation e in Enum.GetValues(typeof(Orientation)))
if(item.HasFlag(e))
i++;

Console.WriteLine(i);

Check if exclusively only these flags set in enumeration

Do "or" on all required flags and compare with input - should be equal. Similar to following, with correct loop to compute value on the left:

var onlyTheseFlagsSet = (value[0] | value[1]) == input;


Related Topics



Leave a reply



Submit