I stumbled upon the usage of the plus (+) operator in an enum definition today, I was surprised to see the accompanying tests pass. Anyone have any idea where this may be documented?
public enum ApprovalItemState
{
Enqueued = 1,
Approved = 2,
Denied = 4,
Acknowledged = 8,
ApprovalAcknowledged = ApprovalItemState.Approved + ApprovalItemState.Acknowledged,
DenialAcknowledged = ApprovalItemState.Denied + ApprovalItemState.Acknowledged
}
[TestClass]
public class ApprovalItemStateTests
{
[TestMethod]
public void AreFlagsDeniedAndAcknowledged()
{
Assert.AreEqual(ApprovalItemState.DenialAcknowledged, ApprovalItemState.Denied | ApprovalItemState.Acknowledged);
}
[TestMethod]
public void IsDenialAcknowledged()
{
Assert.IsTrue(Enum.IsDefined(typeof(ApprovalItemState), ApprovalItemState.Denied | ApprovalItemState.Acknowledged));
Assert.AreEqual(ApprovalItemState.Denied | ApprovalItemState.Acknowledged, (ApprovalItemState)Enum.Parse(typeof(ApprovalItemState), "DenialAcknowledged"));
}
[TestMethod]
public void IsNotDeniedAndApproved()
{
Assert.IsFalse(Enum.IsDefined(typeof(ApprovalItemState), ApprovalItemState.Approved | ApprovalItemState.Denied));
}
}
Reed's answer is of course correct. I just thought I'd add an interesting bit of trivia. First off, when you are inside the enum, all the members of the enum are in scope. This is the only situation in C# in which you can use an enum member via its unqualified name!
public enum ApprovalItemState
{
Enqueued = 1,
Approved = 2,
Denied = 4,
Acknowledged = 8,
ApprovalAcknowledged = Approved | Acknowledged,
DenialAcknowledged = Denied | Acknowledged
}
The second trivia point is that the C# compiler actually allows enum arithmetic involving other enums inside an enum!
enum E
{
E1
}
enum F
{
F1
}
enum G
{
G1 = E.E1 + F.F1
}
Normally that would not be at all legal; you cannot add two dissimilar enums together and you cannot assign the result. The compiler relaxes those rules inside an enum initializer so that you can do things like:
enum MyFlags
{
MyReadOnly = FileFlags.ReadOnly,
...
The C# Language Spec, in 14.5, states:
The following operators can be used on values of enum types: ==, !=, <, >, <=, >= (§7.10.5), binary + (§7.8.4), binary ‑ (§7.8.5), ^, &, | (§7.11.2), ~ (§7.7.4), ++ and -- (§7.6.9 and §7.7.5).
Basically, since the enum is internally stored as an Int32 (that's the default, unless you specify a different storage type), you can use addition like this.
However, it's far more common to use | instead of + to define masks. Also, it would be common to include [Flags] if you're going to use this as a flags enumeration.
From the C# reference on enum:
...Every enumeration type has an underlying type, which can be any integral type except char. The default underlying type of the enumeration elements is int...
By the way, it is more idiomatic (and less error prone) to use | instead of + to combine enum flag values. For example, this mistake won't cause a problem:
DenialAcknowledged =
ApprovalItemState.Denied
| ApprovalItemState.Acknowledged
| ApprovalItemState.Denied
But this mistake will cause a problem:
DenialAcknowledged =
ApprovalItemState.Denied
+ ApprovalItemState.Acknowledged
+ ApprovalItemState.Denied
Approved + Acknowledged is just a constant so it can be assigned as a value to enum element.
Regarding tests -- they work because int values are "happy ones", so (a + b) == (a | b)
However if your change that to something like that:
public enum ApprovalItemState
{
Enqueued = 1,
Approved = 2,
Denied = 7,
Acknowledged = 18,
ApprovalAcknowledged = Approved + Acknowledged,
DenialAcknowledged = Denied + Acknowledged
}
and tests won't pass.
It's not surprising - enums are represented by integral types. You can use other operators as well, although if you're going to use flags (which this example is doing), it's far better to use the [Flags] attribute to define them and better to lay out the bits more clearly:
[Flags]
public enum ApprovalItemState
{
Enqueued = 1 << 0,
Approved = 1 << 1,
Denied = 1 << 2,
Acknowledged = 1 << 3,
ApprovalAcknowledged = ApprovalItemState.Approved | ApprovalItemState.Acknowledged,
DenialAcknowledged = ApprovalItemState.Denied | ApprovalItemState.Acknowledged
}
I'll break down one of these for you.
DenialAcknowledged = ApprovalItemState.Denied + ApprovalItemState.Acknowledged
DenialAcknowledged = 4 + 8
DenialAcknowledged = 12
For this test:
[TestMethod]
public void AreFlagsDeniedAndAcknowledged()
{
Assert.AreEqual(ApprovalItemState.DenialAcknowledged, ApprovalItemState.Denied | ApprovalItemState.Acknowledged);
}
You're checking:
ApprovalItemState.DenialAcknowledged == ApprovalItemState.Denied | ApprovalItemState.Acknowledged
12 == 4 | 8
12 == 0100 | 1000 //bitwise operation
12 == 1100
12 == 12 //convert from binary to decimal
And that is why the test pass. Not exactly straightforward by looking at the code.
Related
This question already has answers here:
Create instance of unknown Enum with string value using reflection in C#
(2 answers)
Closed 3 years ago.
What I have is a string variable that is the name of a enum. I have the integer of the enum. How would I convert that into instance of the enum itself?
Enum TestEnum
{
One = 1,
Two = 2,
Three = 3
}
string str = "TestEnum";
int intValue = 2;
I see many posts that require you to have an instance of the enum to get it's like this highly upvoted answer.
I need to do this at runtime.
Edit:
I am trying to write a class that gets and sets settings in an api that has hundreds of enums that represent settings.
The enums break are categorized by 5 basic setting types represented by five enums. These enums are like:
DoubleValueEnum
IntegerValueEnum
BooleanValueEnum
StringValueEnum
These enums are pointers to settings of type double, integer, string, bool. I believe that underneath the hood they have a database that keeps a table like this:
Type key value Represents
------- ------ ------- ---------------------------------
Double 23 2.745 DoubleValueEnum.DrawingWidth
Integer 5 18 IntegerValueEnum.PenColor
Double 54 15.9245 DoubleValueEnum.GridMajorSpacing
For doubles there is no "lower" enum that it is pointing to. For integer there is a deeper enum like "PenNumber.Red = 1, PenColor.Green = 2.
Hypothetical pen color:
Enum PenColor
{
Red = 1,
Blue = 2,
}
Each of these enums have hundreds of values. Each of these enums has a prewritten function the gets or sets the enum:
GetDoubleEnumValue(int, option)
GetIntegerValueEnum(int, option)
GetBooleanValueEnum(int, option)
GetStringValueEnum(int, option)
SetXXXXXEnumValue(enum, value)
SetDoubleEnumValue(int, int)
SetIntegerValueEnum(int, int)
SetBooleanValueEnum(int, int)
SetStringValueEnum(int, int)
Real example:
SetIntegerValueEnum ((int)IntegerValueEnum.swDxfVersion, (int)swDxfFormat_e.swDxfFormat_R14);
For your given enum definition:
enum TestEnum
{
One = 1,
Two = 2,
Three = 3
}
enum TestEnum2
{
OnePoint1 = 1,
OnePoint2 = 2,
OnePoint3 = 3
}
Use Enum.Parse(Type, string) to parse the string value as an Enum value.
string str = "Two";
TestEnum valueAsEnum = (TestEnum)Enum.Parse(typeof(TestEnum), str);
However, you need to know they type of the Enum definition that you want to parse. If the exact type of the enum value is unknown, but you do know the potential types, then you can iterate through the types and test using the Enum.TryParse
string str = "Two";
object enumValue = null;
if (!Enum.TryParse(typeof(TestEnum), str, true, out enumValue))
Enum.TryParse(typeof(TestEnum2), str, true, out enumValue))
If you do not know the specific type of the enum but you do know the class name, you can use the Type.GetType Method to resolve the type
For this to work you do need to know the full namespace of type that you want to resolve, AND the assembly that the type is defined in must already be loaded.
The syntax to convert an int to an enum is discussed here: https://stackoverflow.com/a/56859286/1690217
In this example, we know that all of the enums reside in the API.Client.Enums namespace:
string str = "TestEnum";
int intValue = 2;
string ns = "API.Client.Enums";
Type enumType = Type.GetType($"{ns}.{str}");
// now we can parse the value:
object value = Enum.ToObject(enumType, (object)intValue);
Usually we do not need to bother with a lot of this conversion just to pass values between systems, the fact that the enum resolves to an integer means that for unknown types we should be able to write our logic to just deal with the integer, and only convert it back to a specific enum when you need it.
It looks like you are trying to use BitWise operations on Enum values to allow a single setting property to represent multiple optional states.
For this sir Enums have support built in if you use the Flags attribute:
There is a good SO dicussion that covers this too: What does the [Flags] Enum Attribute mean in C#?
Lets look at PenColor enum first:
[Flag]
enum PenColor : int
{
None = 0 // 0
Red = 1 << 0, // 1
Green = 1 << 1, // 2
Blue = 1 << 2 // 4
}
By defining the discrete enums with base-2 values, we can now use either bitwise operations on the PenColor enum, or we can use simple integer addition/subtraction:
PenColor cyan = PenColor.Green | PenColor.Blue;
int cyanInt = (int)PenColor.Green + (int)PenColor.Blue;
PenColor cyanCasted = (PenColor)cyanInt;
All of those statements will be equivalent. So potentially this syntax replaces your SetIntegerValueEnum, but it relies on the enum definition being implemented with base-2 values.
To test, this statement should be true:
SetIntegerValueEnum ((int)IntegerValueEnum.swDxfVersion, (int)swDxfFormat_e.swDxfFormat_R14)
== (int)IntegerValueEnum.swDxfVersion + (int)swDxfFormat_e.swDxfFormat_R14)
== IntegerValueEnum.swDxfVersion | swDxfFormat_e.swDxfFormat_R14
The last option will only work if the [Flags] attribute decorates the enum type definition.
You can then use this in switching logic or comparisons
PenColor cyan = PenColor.Green | PenColor.Blue;
bool hasBlue = cyan & PenColor.Blue == PenColor.Blue;
// you can also use the slower Enum.HasFlag
hasBlue = cyan.HasFlag(PenColor.Blue);
I have the following enums defined in my code:
[Flags]
public enum Symbol
{
A,
B,
}
public enum Production
{
AA = Symbol.A | Symbol.A,
AB = Symbol.A | Symbol.B,
BA = Symbol.B | Symbol.A, // <- this will obviously not work
}
I was planning to make use of enums as they eventually would prevent unwanted Symbols to be used for Productions. The problem is that the following code does not produce the output that I'm after:
Productions product1 = (Productions) (Symbol.A | Symbol.A); // Production.AA
Productions product2 = (Productions) (Symbol.A | Symbol.B); // Production.AB
Productions product3 = (Productions) (Symbol.B | Symbol.A); // Production.AB (and not Production.BA as I would like)
I completely understand why this is happening, but was wondering if there is a combination of bitwise operators that I could use to make it work as I originally intended?
Or maybe in general I'm trying to use enums in a incorrect way, therefore should switch to chars or even custom structs?
Well, because you need to take care of the order of A and B than you should use some operation that is not commutative. I would better suggest the approach where each position should have the assigned weight and you can have simple addition of symbols with weights. Since Enums are ints you can assign to each position a weight of 10^i where i is the zero-based index of the position looking from right to left. Even then you can have calculations for even more Symbols. This is like with classic Arabic numbers but with your symbols instead of regular digits. The code can be like this:
[Flags]
public enum Symbol
{
A,
B,
}
public enum Production
{
AA = Symbol.A *10 + Symbol.A, //0
AB = Symbol.A *10 + Symbol.B, //1
BA = Symbol.B *10 + Symbol.A, //10
}
You are trying to perform pattern matching. This is not what enums are for. Languages such as F# have a great mechanism built-in to do this, for example:
match expression with
| pattern_1 -> expression_1
| pattern_2 -> expression_2
| pattern_n -> expression_n
But C# does not have this [yet]. There is a great project to add a library to C# to give it this functionality called Functional C#. I think that library is your best bet.
As you want to keep information about both the value and posititon, you would need to use different enum value for different values at different positions:
[Flags]
public enum Symbol {
FirstA = 1,
FirstB = 2,
SecondA = 4,
SecondB = 8
}
public enum Production {
AA = Symbol.FirstA | Symbol.SecondA,
AB = Symbol.FirstA | Symbol.SecondB,
BA = Symbol.FirstB | Symbol.SecondA
}
Is there a way to add an "All values" option to an enum without having to change its value every time a new value is added to the enum?
[Flags]
public enum SomeEnum
{
SomeValue = 1,
SomeValue2 = 1 << 1,
SomeValue3 = 1 << 2,
SomeValue4 = 1 << 3,
All = ?
}
Update:
Ended up inheriting from long and using long.MaxValue for All option.
Since you should define the empty value in a Flags enum such as None = 0, the simplest way of defining the Allvalue is by simply inverting all the bits inNone`.
[Flags]
enum MyEnum
{
None = 0,
A = 1,
B = 2,
C = 4,
...
All = ~None
}
Note that ~0 instead of ~None will not work for unsigned backing types as that is -1, which is not a valid value for unsigned.
Edit: Answer was modified to use an inverted None instead of an explicit constant such as 0x7FFFFFFF or ~0, as this also works for unsigned
It should be like this:
[Flags]
public enum SomeEnum
{
SomeValue = 1,
SomeValue2 = 1 << 1,
SomeValue3 = 1 << 2,
SomeValue4 = 1 << 3,
All = SomeValue | SomeValue2 | SomeValue3 | SomeValue4
}
An enum can be made of many different length integer types (short, int, long). This makes the #FFFFFFFF solution inappropriate (as pointed out in #MarcGravell comment).
An enum can be made of unsigned types (uint for isntance). This makes the -1 solution inappropriate.
My best bet is, maintenance-free:
All = ~0
The Idea is to use the behavior of the enum to calculate the last value.
Add Last field after all 'real' enum values.
Add All field equals to (Last << 1) - 3.
[Flags]
public enum SomeEnum
{
SomeValue = 1,
SomeValue2 = 1 << 1,
SomeValue3 = 1 << 2,
SomeValue4 = 1 << 3,
// Do not add values after this
Last,
All = (Last << 1) - 3,
}
I answered it at: How to use Enum with aditional options (All, None)
You can check my blog at Enum Trick for more information and ideas.
No, there is nothing built is that will make such an All option automatically update when the Enum changes.
You may want to have a special value (monitor value) that means All (say -1), even if it is not the bitwise sum of all of the options.
An alternative is to use a value that has all of the bits switched on:
All = 0xFFFFFFFF
You can use a little trick
(SomeEnum)( (1 << ( Enum.GetValues( typeof(SomeEnum) ).Length ) ) -1 )
If you added a 'None' Enum name with value = 0 ( None = 0, ) then you need to put a '-1' after the Length.
This is possible if you're okay with a static readonly field in a separate type, rather than as a const enum field:
[Flags]
public enum SomeEnum
{
None = 0,
SomeValue = 1,
SomeValue2 = 1 << 1,
SomeValue3 = 1 << 2,
SomeValue4 = 1 << 3,
}
public static class SomeEnumUtility {
private static readonly SomeEnum[] _someEnumValues = (SomeEnum[])Enum.GetValues( typeof(SomeEnum) );
public static readonly SomeEnum SomeEnum_All = GetSomeEnumAll();
// Unfortunately C# does not support "enum generics" otherwise this could be a generic method for any Enum type
private static SomeEnum GetSomeEnumAll() {
SomeEnum value = SomeEnum.None; // or `(SomeEnum)0;` if None is undefined.
foreach(SomeEnum option in _someEnumValues) {
value |= option;
}
return value;
}
}
Then you can get SomeEnumUtility.SomeEnum_All. As it's a static readonly the computation is only performed once, in a thread-safe manner.
As I wrote in the code-comment, it's unfortunate that C# does not support enum generics, otherwise you could do this:
private static TEnum GetEnumAllFlags<TEnum>() where TEnum : enum {
TEnum[] allValues = Enum.GetValues<TEnum>();
TEnum value = (TEnum)0;
foreach(TEnum option in allValues) {
value |= option;
}
return value;
}
Oh well :(
public static T EnumSetAll<T>() where T : struct, Enum
{
string str = string.Join(", ", Enum.GetNames(typeof(T)));
if (Enum.TryParse<T>(str, out var e))
return e;
return default;
}
Let's say I have this enum:
[Flags]
public enum SomeType
{
Val1 = 0,
Val2 = 1,
Val3 = 2,
Val4 = 4,
Val5 = 8,
Val6 = 16,
All = Val1 | Val2 | Val3 | Val4 | Val5 | Val6
}
and some variables:
SomeType easyType = SomeType.Val1 | SomeType.Val2;
SomeType complexType = SomeType.All;
If I want to loop through values of the first enum I can simply do:
foreach(string s in easyType.ToString().Split(','))
{ ... }
However, when I try to apply the same approach to the 'complexType' I get value 'All', which is of course valid because it's also one of possible values of the enum. But, is there a neat way to actually see of what values is the SomeType.All created of? I know I could make a manual loop through all the values like that:
if(complexType.HasFlag(ManualType.Val1) && ...
var result = string.Join(",",
Enum.GetValues(typeof(SomeType))
.Cast<SomeType>()
.Where(v => complexType.HasFlag(v)));
You can write an extension method to avoid repeating yourself.
Maybe you need to enumerate the enum values and test each one:
foreach (SomeType item in Enum.GetValues (typeof (SomeType))
{
if ((complexType & item) == item)
{
//...
}
}
Here's one possible way to do it, building on Danny Chen's answer:
public IEnumerable<T> GetFlags<T>(Predicate<int> hasFlag)
{
return GetEnumFlags<T>().Where(f => hasFlag(f)).Cast<T>();
}
private IEnumerable<int> GetEnumFlags<T>()
{
return Enum.GetValues(typeof(T)).Cast<int>().Where(IsPowerOfTwoOrZero);
}
private bool IsPowerOfTwoOrZero(int v)
{
return ((v & (v-1)) == 0);
}
Usage:
void Main()
{
SomeType easyType = SomeType.Val1 | SomeType.Val2;
SomeType complexType = SomeType.All;
GetFlags<SomeType>(v => easyType.HasFlag((SomeType)v));
GetFlags<SomeType>(v => complexType.HasFlag((SomeType)v));
}
Note this will work for Enums based on types castable to int. You can create similar methods for long etc.
If you're using an enum to represent data that has some deeper level of complexity (arbitrary groups of elements, "darkness" of colour, etc.) and struggling because of that, I'd suggest that an enum is the wrong programming construct to be using.
Using an enum for these tasks will always be error prone: if I add a new colour to your enum, I have to remember to add it to "Bright" or "Dark" too. That makes your code just as error prone for developers as the original problem. What you could do, however, is define a class or struct for colour that has a property indicating whether it's bright or not. Then you'll have clear, understandable functionality - implemented in a way that doesn't give spurious results as when you're trying to misuse a simpler language feature.
That, for example, is why Color is a struct...
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