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
Why Filesystemwatcher Doesn't Work in Linux Container Watching Windows Volume
Differencebetween an Int and an Integer in Java and C#
How to Decompile a .Net Exe into Readable C# Source Code
How Using Try Catch for Exception Handling Is Best Practice
C# Switch Statement Limitations - Why
Web App Blocked While Processing Another Web App on Sharing Same Session
Using Linq to Group a List of Objects into a New Grouped List of List of Objects
Cross-Thread Operation Not Valid
Sqlcommand Parameters Add VS. Addwithvalue
How to Check If an Object Is Nullable
How to Close a Login Form and Show the Main Form Without My Application Closing
Convert String[] to Int[] in One Line of Code Using Linq
How to Make Sure That String Is Valid JSON Using JSON.Net