Reputation: 3376
Suppose I have the following:
[Flags]
public enum Options : long
{
None = 0,
Flag1 = 0x00000001,
Flag2 = 0x00000002,
Flag3 = 0x00000004,
Flag4 = 0x00000008,
Flag5 = 0x00000010,
// ...
FlagV = 0x10000000000,
FlagW = 0x20000000000,
FlagX = 0x40000000000,
FlagY = 0x80000000000,
FlagZ = 0x100000000000
}
Currently, to determine if a flag is set, I am doing this:
(myOptions & (long)Options.Flag1) == (long)Options.Flag1
How do I determine whether ANY flag above FlagV (e.g. FlagW, FlagX, etc.) is set and retrieve its value (e.g. if FlagW, FlagX, and FlagZ are set, I want to retrieve the value of FlagW)? In other words, is there an alternative to this:
if ((myOptions & (long)Options.FlagW) == (long)Options.FlagW)
return (long)Options.FlagW;
else if ((myOptions & (long)Options.FlagX) == (long)Options.FlagX)
return (long)Options.FlagX;
else if ((myOptions & (long)Options.FlagY) == (long)Options.FlagY)
return (long)Options.FlagY;
// etc.
Upvotes: 1
Views: 166
Reputation: 22261
First, you might want to reconsider the design which led you to more than 32 flags, as that sounds troublesome in its own right.
Beyond that, consider that you are only doing bit arithmetic, so something like the following is both efficient (compiles to a couple instructions), and easy to maintain:
public enum Options : long
{
FlagA = 0x00000001,
// ...
FlagZ = 0x80000000,
// ...
HighFlags = 0xffff0000,
LowFlags = 0x0000ffff
}
Then you can check for any HighFlags
by doing (options & Options.HighFlags) != 0
and get only HighFlags
with options & Options.HighFlags
.
If you cannot modify the enum, or don't want to rely upon specific values, you could also or
the values together at runtime:
public static class OptionsHelper
{
private readonly static Options HighFlags = Options.FlagM
| Options.FlagN
// ...
| Options.FlagZ;
public static bool HasHighFlags(this Options opt)
{
return (opt & HighFlags) != 0;
}
public static Options GetHighFlags(this Options opt)
{
return (opt & HighFlags);
}
public static IEnumerable<Options> GetSetHighFlags(this Options opt)
{
var highFlags = GetHighFlags(opt);
if (highFlags != 0)
{
for (ulong cFlag = 1; cFlag != 0; cFlag <<= 1)
{
if ((highFlags & cFlag) != 0)
{
yield return (Options)cFlag;
}
}
}
}
}
Used as an extension method (options.HasHighFlags()
) or options.GetSetHighFlags().First()
.
Upvotes: 1
Reputation: 67223
You can simply do something like this:
if (optons & 0xfe0000000000) // Typecasts will be needed
// One of those flags is set.
Also, note that newer versions of .NET support the options.HasFlag()
method, which simplifies determining whether or not a flag is defined.
In fact, I didn't test it but you should be able to do something like this:
if (optons.HasFlag(0xfe0000000000)) // Typecasts will be needed
// One of those flags is set.
Upvotes: 0
Reputation: 39085
This will give you a list of flags set in myOptions
:
var flags = Enum.GetValues(typeof(Options))
.Where(f => myOptions.HasFlag(f))
.ToList();
EDIT: it looks like your myOptions
is actually a long, otherwise your code wouldn't have compiled since you can't apply &
to an enum and a long. So try this instead:
var enumVal = (Options)myOption;
var flags = Enum.GetValues(typeof(Options))
.Where(f => enumVal.HasFlag(f))
.ToList();
Upvotes: 2
Reputation: 6016
You can iterate through all Options values.
var currentVal = Options.FlagV | Options.FlagW;
foreach (Options enumVal in Enum.GetValues(typeof(Options)))
if (enumVal > Options.FlagV && (enumVal & currentVal) == enumVal)
//Do stuff
Upvotes: 3