Most Common C# Bitwise Operations on Enums

Bitwise operations on Enum Flag

Try ^; please, notice that new is a keyword in C# and that's why should be put as @new when it's used as a name:

  var @new = MyFlag.Foo | MyFlag.Quuz; // 1001
var old = MyFlag.Foo | MyFlag.Baz; // 0101

var xor = @new ^ old; // <- xor

Test

  // 1100
Console.Write(Convert.ToString((int)xor, 2));

Finally, it seems that you are looking for bitwise & to obtain added and removed values:

  MyFlag added = xor & @new;  // 1000
MyFlag removed = xor & old; // 0100

& operator with enum values in C#

You assign values to the enums, and the operators | and & work on the enum values, like they would work on the corresponding values.

You have set the values of the enum values yourself, and you have not set them orthogonal. Since integers are in fact bitstrings (with fixed length), you can see it as a 32-dimensional vector (with every vector element having domain {0,1}). Since you defined for instance Bottom as 3, it means that Bottom is actually equal to Right | Top, since:

Right | Top
1 | 2 (integer value)
01 | 10 (bitwise representation)
11 (taking the bitwise or)
Bottom

So that means that if you write &, this is a bitwise AND, and |, is a bitwise OR on the values of the enum values.

So if we now evaluate it, we get:

(Orientations.Left|Orientations.Bottom) & (Orientations.Right|Orientations.Top)
(0 | 3 ) & (1 | 2)
3 & 3
3
Orientations.Bottom

If you want to define four orthogonal values, you need to use powers of two:

[Flags]
public enum Orientations {
Left = 1, // 0001
Right = 2, // 0010
Top = 4, // 0100
Bottom = 8 // 1000
};

Now you can see the enum as four different flags, and and the & will create the intersection, and | the union of the flags. In comment the bitwise representation of each value is written.

As you can see, we can now see Left, Right, Top and Bottom as independent elements, since we can not find a monotonic bitwise construction ( to combine Left, Right and Top to construct Bottom (except negation).

Bitwise or-ing enums using generics

There is no way to apply a generic constraint on a type that that type be an Enum, or to apply a constraint that the type overloads the | operator, so anything that you do, by necessity, won't be able to maintain entirely static typing.

What you can do is change the enum to its underlying integer type, do the aggregation, and then cast it back. The problem is that you can't (easily) solve is dynamically determining the underlying type and performing the bitwise or on that type (again due to a lack of constraints on a type having an overload of the | operator). If you can assume that the underlying type of the enum is an int (or any smaller type) then you can do it, but if the underlying type of the enum is say a long then this code would break. There's also the fact that non-enum values can be used for T, and those types may or may not function properly when passed to this method.

private static T CombineFlags<T>(params T[] flags) where T : struct, IConvertible
{
int n = flags.Select(flag => Convert.ToInt32(flag))
.Aggregate((x, y) => x | y);
return (T)(object)n;
}

Flags and operation on enums? C#

Behind the scenes, the enumeration is actually an int.

<< is the Bitwise Left Shift Operator

An equivalent way of writing this code is :

[Flags]
public enum EAccountStatus
{
None = 0,
FreeServiceApproved = 1,
GovernmentAccount = 2,
PrivateOrganisationAccount = 4,
All = 8
}

Please note, that this enumeration has the Flag attribute

As stated in the msdn:

Use the FlagsAttribute custom attribute for an enumeration only if a
bitwise operation (AND, OR, EXCLUSIVE OR) is to be performed on a
numeric value.

This way, if you want to have multiple options set you can use:

var combined =  EAccountStatus.FreeServiceApproved  | EAccountStatus.GovernmentAccount 

which is equivalent to:

  00000001  // =1 - FreeServiceApproved 
| 00000010 // =2 - GovernmentAccount
---------
00000011 //= 3 - FreeServiceApproved and GovernmentAccount

this SO thread has a rather good explanation about the flags attribute

Compare two enums w/bitwise for a single True result?

if you want to see the articles where the Target is either LikesFishing or Adult,

try this:

 var target = Targets.LikesFishing | Targets.Adult;
var articles = db.Articles.Where(x => (int)(x.Targets & target) > 0 );

and oh, yes, add the [FlagsAttribute] to the enum:

[Flags]
public enum Targets
{ NotSet = 0, Anonymous = 1, Everyone = 2,
Adult = 4, Child = 8, LikesFishing = 16 }

How do I perform a bitwise OR on .NET enums in script running with NLua?

The best way to combine Enum flags with NLua is using the helper function luanet.enum

value = luanet.enum (BindingFlags, 'NonPublic,Instance')

Example: https://github.com/codefoco/NLuaBox/blob/00af36aa480281ae33835173430a806c54c2f9dc/Resources/source/OutputViewController.lua#L41

HasFlag for a combination of bitwise and single-value Enums

You would have to either define KeyCode like this

[Flags]
enum KeyCode {
A = 1,
B = 2,
C = 4,
D = 8,
E = 16
}

Or to calculate the combined value with

return (int)Math.Pow(2, (int)Key) + (int)State + (int)Modifiers;

Most efficient way of looking up the results of a Bitwise operation

Assuming that you want to work with the enums directly, the base types of all enums are integers. With this knowledge, you can take the "unbounded" nature of integers and bring the goodness of enums.

enum Greetings {
HELLO = 1,
WORLD = 2,
AND = 4,
SO = 8,
ON = 16
}

So if you get an integer back from the callee (doing interop?), you can then do this:

Greetings greet = (Greetings)theIntegerResult;

From there on, you can do your bitwise operations to see which fields are set.

bool isHelloSet = (greet & Greetings.HELLO) == Greetings.HELLO;
bool isWorldSet = (greet & Greetings.WORLD) == Greetings.WORLD;
bool isAndSet = (greet & Greetings.AND) == Greetings.AND;
bool isSoSet = (greet & Greetings.SO) == Greetings.SO;
bool isOnSet = (greet & Greetings.ON) == Greetings.ON;


Related Topics



Leave a reply



Submit