Using a bitmask in C# - c#

Let's say I have the following
int susan = 2; //0010
int bob = 4; //0100
int karen = 8; //1000
and I pass 10 (8 + 2) as a parameter to a method and I want to decode this to mean susan and karen
I know that 10 is 1010
but how can I do some logic to see if a specific bit is checked as in
if (condition_for_karen) // How to quickly check whether effective karen bit is 1
Right now all i can think of is to check whether the number i passed is
14 // 1110
12 // 1100
10 // 1010
8 // 1000
When I have a larger number of actual bits in my real world scenario, this seems impractical, what is a better way using a mask to just check whether or not I meet the condition for just karen?
I can think of shifting left then back then shifting right then back to clear bits other than the one I'm interested in, but this also seems overly complex.

The traditional way to do this is to use the Flags attribute on an enum:
[Flags]
public enum Names
{
None = 0,
Susan = 1,
Bob = 2,
Karen = 4
}
Then you'd check for a particular name as follows:
Names names = Names.Susan | Names.Bob;
// evaluates to true
bool susanIsIncluded = (names & Names.Susan) != Names.None;
// evaluates to false
bool karenIsIncluded = (names & Names.Karen) != Names.None;
Logical bitwise combinations can be tough to remember, so I make life easier on myself with a FlagsHelper class*:
// The casts to object in the below code are an unfortunate necessity due to
// C#'s restriction against a where T : Enum constraint. (There are ways around
// this, but they're outside the scope of this simple illustration.)
public static class FlagsHelper
{
public static bool IsSet<T>(T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
return (flagsValue & flagValue) != 0;
}
public static void Set<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
flags = (T)(object)(flagsValue | flagValue);
}
public static void Unset<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
flags = (T)(object)(flagsValue & (~flagValue));
}
}
This would allow me to rewrite the above code as:
Names names = Names.Susan | Names.Bob;
bool susanIsIncluded = FlagsHelper.IsSet(names, Names.Susan);
bool karenIsIncluded = FlagsHelper.IsSet(names, Names.Karen);
Note I could also add Karen to the set by doing this:
FlagsHelper.Set(ref names, Names.Karen);
And I could remove Susan in a similar way:
FlagsHelper.Unset(ref names, Names.Susan);
*As Porges pointed out, an equivalent of the IsSet method above already exists in .NET 4.0: Enum.HasFlag. The Set and Unset methods don't appear to have equivalents, though; so I'd still say this class has some merit.
Note: Using enums is just the conventional way of tackling this problem. You can totally translate all of the above code to use ints instead and it'll work just as well.

Easy Way:
[Flags]
public enum MyFlags {
None = 0,
Susan = 1,
Alice = 2,
Bob = 4,
Eve = 8
}
To set the flags use logical "or" operator |:
MyFlags f = new MyFlags();
f = MyFlags.Alice | MyFlags.Bob;
And to check if a flag is included use HasFlag:
if(f.HasFlag(MyFlags.Alice)) { /* true */}
if(f.HasFlag(MyFlags.Eve)) { /* false */}

if ( ( param & karen ) == karen )
{
// Do stuff
}
The bitwise 'and' will mask out everything except the bit that "represents" Karen. As long as each person is represented by a single bit position, you could check multiple people with a simple:
if ( ( param & karen ) == karen )
{
// Do Karen's stuff
}
if ( ( param & bob ) == bob )
// Do Bob's stuff
}

I have included an example here which demonstrates how you might store the mask in a database column as an int, and how you would reinstate the mask later on:
public enum DaysBitMask { Mon=0, Tues=1, Wed=2, Thu = 4, Fri = 8, Sat = 16, Sun = 32 }
DaysBitMask mask = DaysBitMask.Sat | DaysBitMask.Thu;
bool test;
if ((mask & DaysBitMask.Sat) == DaysBitMask.Sat)
test = true;
if ((mask & DaysBitMask.Thu) == DaysBitMask.Thu)
test = true;
if ((mask & DaysBitMask.Wed) != DaysBitMask.Wed)
test = true;
// Store the value
int storedVal = (int)mask;
// Reinstate the mask and re-test
DaysBitMask reHydratedMask = (DaysBitMask)storedVal;
if ((reHydratedMask & DaysBitMask.Sat) == DaysBitMask.Sat)
test = true;
if ((reHydratedMask & DaysBitMask.Thu) == DaysBitMask.Thu)
test = true;
if ((reHydratedMask & DaysBitMask.Wed) != DaysBitMask.Wed)
test = true;

To combine bitmasks you want to use bitwise-or. In the trivial case where every value you combine has exactly 1 bit on (like your example), it's equivalent to adding them. If you have overlapping bits however, or'ing them handles the case gracefully.
To decode the bitmasks you and your value with a mask, like so:
if(val & (1<<1)) SusanIsOn();
if(val & (1<<2)) BobIsOn();
if(val & (1<<3)) KarenIsOn();

One other really good reason to use a bitmask vs individual bools is as a web developer, when integrating one website to another, we frequently need to send parameters or flags in the querystring. As long as all of your flags are binary, it makes it much simpler to use a single value as a bitmask than send multiple values as bools. I know there are otherways to send data (GET, POST, etc.), but a simple parameter on the querystring is most of the time sufficient for nonsensitive items. Try to send 128 bool values on a querystring to communicate with an external site. This also gives the added ability of not pushing the limit on url querystrings in browsers

Related

Check if an enum contains more than one flag [duplicate]

This question already has answers here:
How do I check if more than one enum flag is set?
(5 answers)
Test that only a single bit is set in Flags Enum [duplicate]
(1 answer)
Closed 2 years ago.
I am trying to check if an "enum instance" contains more than one flag.
[Flags]
public enum Foo
{
Bar = 1,
Far = 2
}
var multiState = Foo.Bar | Foo.Far;
MoreThanOneFlag(multiState); // True
var singleState = Foo.Bar;
MoreThanOneFlag(singleState); // False
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
Note, I do not care which Flags the "instance" contains, I just want to know if there are more than one.
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)
You can use the binary logarithm function on the enum value and then check if the result is an integer.
The following example defines am Extension Method helper, which returns true when multiple flags are set:
HelperExtenxsions.cs
public static class HelperExtenxsions
{
public static bool HasMultipleFlags(this IConvertible enumValue)
{
return Math.Log(enumValue.ToInt32(CultureInfo.InvariantCulture.NumberFormat), 2) % 1 != 0;
}
}
Foo.cs
[Flags]
public enum Foo
{
Bar = 1,
Far = 2
}
Program.cs
public static void Main()
{
var enumValue = Foo.Bar | Foo.Far;
Console.WriteLine(enumValue.HasMultipleFlags()); // Prints 'True'
enumValue = Foo.Bar;
Console.WriteLine(enumValue.HasMultipleFlags()); // Prints 'False'
}
You can use Enum.GetValues in conjunction with Enum.HasFlag(Enum) to iterate over each constant & determine if the bit field(s) are set in the current Instance and return its count.
[Flags]
public enum Foo
{
One = 1,
Two = 2,
Four = 4,
Eight = 8
}
var state1 = Foo.One;
var state2 = Foo.Two;//
var state3 = Foo.One | Foo.Two;
var state4 = Foo.Two | Foo.Four;
Console.WriteLine(MoreThanOneFlag(state1));//false
Console.WriteLine(MoreThanOneFlag(state2));//false
Console.WriteLine(MoreThanOneFlag(state3));//true
Console.WriteLine(MoreThanOneFlag(state4));// true
private static bool MoreThanOneFlag<TEnum>(TEnum state) where TEnum : Enum
{
var names = Enum.GetValues(typeof(TEnum));
var Flagcounter = names.OfType<TEnum>().Where(x=>state.HasFlag((TEnum)x)).Count();
return Flagcounter > 1 ? true : false;
}
Note: While Enum.HasFlags may not the apt solution if you're app demands performance but it is much reliable, clean, and makes the code very obvious and expressive
Reference:
C# Enum.HasFlag vs. Bitwise AND Operator Check

console.cs IsHandleRedirected oddity

MS' own console.cs has the following function, used by the IsInput/Output/ErrorRedirected APIs.
private static bool IsHandleRedirected(IntPtr ioHandle) {
// Need this to use GetFileType:
SafeFileHandle safeIOHandle = new SafeFileHandle(ioHandle, false);
// If handle is not to a character device, we must be redirected:
int fileType = Win32Native.GetFileType(safeIOHandle);
if ((fileType & Win32Native.FILE_TYPE_CHAR) != Win32Native.FILE_TYPE_CHAR) // <--- ??
return true;
// We are on a char device.
// If GetConsoleMode succeeds, we are NOT redirected.
int mode;
bool success = Win32Native.GetConsoleMode(ioHandle, out mode);
return !success;
}
I don't understand the logic on the line marked (by me) with // <--- ??. It would have made sense that if (fileType != Win32Native.FILE_TYPE_CHAR) return true;, but I don't follow why it's masked with & Win32Native.FILE_TYPE_CHAR before comparing.
To make it more confusing, the constant FILE_TYPE_CHAR is the single bit 0x0002 which is also shared by FILE_TYPE_PIPE = 0x0003, so the if statement in question will not return true; if the file handle refers to a pipe (maybe relying on GetConsoleMode to fail afterwards??).
Any insight into why that code was written the way it is would be much appreciated. Thanks.
It used to be a common technique when working with flags enums.
You use bitwise and between the input value and the flag you want to check, and compare the results with the flag itself. If the input value contains the flag, the condition is true, if not, the condition is false.
Let me illustrate that with a simple example:
Suppose you have this enum:
[Flags]
enum test
{
None = 0, // 0000
One = 1, // 0001
Two = 2, // 0010
Four = 4, // 0100
Eight = 8 // 1000
}
And you have a value you want to test. Let's say 13. When you convert 13 to a four bit binary number you get 1101 - so you can do something like this:
var input = 13;
if(((test)input & test.One) == test.One) // that's testing if 1101 & 0001 = 0001
{
// The result of this condition is true, since 13 is an odd number.
}
However, since .Net 4.0 you can simply use the HasFlag method instead:
if(input.HasFlag(test.One))
{
// The result of this condition is true, since 13 is an odd number.
}
For more information you can read Ending the Great Debate on Enum Flags

Strategy for detecting (via Reflection) if Enum is of type "Flags" in C#

I'm using Reflection to read types inside an assembly (to generate code). I can see that some enumerations should have been marked with the [Flags] attribute but whoever wrote those enums forgot to add this attribute.
Is there any reliable way of detecting when an enum can be considered a "Flags" enum?
My strategy at the moment is to read the enum in descending order, and checking if the value of element(last -1) * 2 == element(last).
That works great in most cases, except when I have enums with 0, 1, and 2 values (which could be flags or not).
edit:
Example of an enum that I'd like to detect as being flags:
public enum EnumIsFlag1
{
ItemA = 2,
ItemB = 4,
ItemC = ItemA + ItemB,
ItemD = 32,
ItemE = 64,
}
edit: My question is not a duplicate... The moderator clearly didn't read my question
Clearly, this problem can only be solved heuristically but I understand that's what you are after.
Typically, flags enums have most members with a single bit set. So I would count the number of members that have only a single bit set (e.g. that are a power of two).
Then, you can devise a heuristic such as:
//Is this a flags enum?
var totalCount = ...;
var powerOfTwoCount = ...;
if (totalCount < 3) return false; //Can't decide.
if (powerOfTwoCount >= totalCount * 0.95) return true; //Looks like flags
//Probably need some cases for small values of totalCount.
The only reason multiple bits could be set in a legitimate flags enum is combinations of flags. But the number of such enum items is usually small.
This answer goes into detail about the differences between the two, and they are very minor: just some string formatting behaviour.
The strict answer to your question is that any type can be checked for the flags enum using reflection. Anything else just needs to be checked by a human. You can check for the Flags attribute directly like this;
[Flags]
enum Foo
{
A = 0,
B = 1,
C = 4
}
enum Bar
{
A = 0,
B = 1,
C = 4
}
bool IsFlagsEnum(Type t)
{
var attr = t.GetCustomAttributes(typeof(FlagsAttribute), true).FirstOrDefault();
var result = attr != null;
return result;
}
Console.WriteLine(IsFlagsEnum(typeof(Foo))); // True
Console.WriteLine(IsFlagsEnum(typeof(Bar))); // False

Operator && cannot be applied

I am testing an example snippet that I found as an answer on another Question
However the compiler is spitting out this "Operator && cannot be applied to operands of type long and bool".
Why does it do this? As I read the code, it says "If mask and permission are greater than 0 return success bool"
Am I reading this wrong?
(Also, no one called it out as a bad example so I expected it to work. Not that I am a copy-paste coder)
bool CheckMask( long Mask, long TestPermission ) {
return Mask && TestPermission > 0;
}
long mask = 4611686844973976575;
const long MASK_ViewListItems = 0x0000000000000001;
bool HasPermission_ViewListItems = CheckMask(mask, MASK_ViewListItems);
// HasPermission_ViewListItems is true
const long MASK_UseClientIntegration = 0x0000001000000000;
bool HasPermission_UseClientIntegration = CheckMask(mask, MASK_UseClientIntegration);
// HasPermission_UseClientIntegration is false
There are an awful lot of similar questions on StackOverflow and I've clicked through most of them, there's a big list to my right as I type. None have applied to my situation, at least I was able to see the relation between the answers and my problem.
You're using && (conditional AND, only valid for bool operands) instead of & (bitwise AND, valid for bool operands or integer operands) - I suspect you want the latter, and you should also use brackets due to precedence rules. I'd change the parameter names to follow .NET naming conventions, too - and make it static as it doesn't rely on any state:
static bool CheckMask(long mask, long testPermission)
{
return (mask & testPermission) > 0;
}
You might also want to change to using an enum instead of long:
[Flags]
public enum Permissions
{
ViewListItems = 1 << 0,
...
UseClientIntegration = 1 << 9
}
static bool CheckMask(Permissions mask, Permissions testPermission)
{
return (mask & testPermission) != 0;
}
I'm guessing this is what you want:
(Mask & TestPermission) != 0
So, you need:
a bitwise & (instead of && that applies only to bool)
and I'm guessing you want to check if any bit is set including the sign bit (so != instead of >).

A way to parse .NET enum string or int value attributed with 'Flags'

There is a nice way of figuring out the enumeration element using the following approach:
// memberType is enum type
if (Enum.IsDefined(memberType, valueString))
{
return Enum.Parse(memberType, valueString);
}
else
{
try
{
var underlyingValue = Convert.ChangeType(valueString, Enum.GetUnderlyingType(memberType));
if (Enum.IsDefined(memberType, underlyingValue))
{
return underlyingValue;
}
}
catch...
}
This works like charm. Except for values built from enumerations marked with FlagsAttribute. For example, for this enum and a value:
[Flags]
enum MyEnum {
One = 0x1,
Two = One << 1,
Four = One << 2,
Eight = One << 3
}
var e = MyEnum.One | MyEnum.Eight;
the approach above doesn't work. Looks like the only way to make it work is to try to get all the enum values and bitwise AND them with the input value. That's somewhat tedious though. So do you know any better way?
Answer:
The final method looks like this:
var parsed = Enum.Parse(memberType, valueString);
decimal d;
if (!decimal.TryParse(parsed.ToString(), out d))
{
return parsed;
}
throw new ArgumentOutOfRangeException(memberInfo.Name, valueString, "Bad configuration parameter value.");
I guess a better question to ask, how to detect bad values.
Looks like there is a nice work around found in C# 4.0 in a Nutshell. From here. Once you Parse the integer value to the enum, you can use this and see if the value is valid. This will work for combined flags.
static bool IsFlagDefined(Enum e)
{
decimal d;
return !decimal.TryParse(e.ToString(), out d);
}
This is expected behavior, as you can get values that do not correspond to the flags. For example, let's assume value a = 1, b = 2, c = 4, d= 8, etc. (Just standard binary progression). It is possible to have a 5 for the value (a & c) or 7 (a, b & c).
Why don't you just use Enum.Parse()
var test = MyEnum.One | MyEnum.Eight;
var str = test.ToString();
var back = (MyEnum) enum.Parse(typeof(MyEnum), str); // this returns MyEnum.One | MyEnum.Eight
First try to convert your string to "undelying type", if succeded - cast it to MyEnum and that's what you needed.
If convert failed - try to use Enum.Parse.
If it also fails - that is a very bad input (throw exception)
Update:
No testing for int conversion is needed enum.Parse(typeof(MyEnum), "9") returns MyEnum.One | MyEnum.Eight (tested in Framework 2.0 to 4.0)
Update 2:
So question really was "How to figure out bad values?". Dirty solution:
var res = Enum.Parse(targetType, str);
bool isBad;
try
{
Convert(res.ToString(), underType);
isBad = true;
}
catch
{
// convert failed
isBad = false;
}
if (isBad)
throw new Exeption();
return res;
But it is very dirty and throwing exception is expensive operation so there is performance penalty here... But it works)
Use Enum.Parse. Then check on the returned value, that no bits are set that are not valid flags. To do this, make a bitmask containing all the valid values, and OR them together with the value. If the result differs from the mask, some bits was set, that are not valid flags. This is not too tedious (but you will need to check whether the Enum is in fact a Flags enum, before applying this logic - if it is not a Flags enum, use IsDefined).
The code could go something like this; and you could store the mask per type pre-computed if you think it might be too expensive to calculate each time (it's probably not, but will depend on your case):
object value = Enum.Parse(memberType, valueString);
int numericValue = (int)value;
int definedMask = Enum.GetValues(memberType).Cast<int>().Aggregate(0, (v,a) => v | a);
if ((definedMask | numericValue) != definedMask)
throw new InvalidOperationException(String.Format("{0} is not a valid {1} value.", valueString, memberType.Name));
return value;
That is a nice question, your suggestion
try to get all the enum values and
bitwise AND them with the input value
after 10 minutes of research looks really reasonable.. ^^
I found a nice link regarding similar issue, a guy there spent quite some time to write this article, maybe you will find it interesting too.
Breaking down C# Flags enums into individual values for comparison

Categories