Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine enumerations with flags?

Tags:

c#

enums

I have an enumeration with flags. I want to declare a variable with n different flags. n > 1 in this case.

public enum BiomeType {
    Warm = 1,
    Hot = 2,
    Cold = 4,
    Intermediate = 8,

    Dry = 16,
    Moist = 32,
    Wet = 64,
}

Okay - one variant is to cast each flag into an byte and cast the result to my enum.

BiomeType bType = (BiomeType)((byte)BiomeType.Hot + (byte)BiomeType.Dry)

But this is kinda messy - imho. Is there an more readable way to combine flags?

like image 886
boop Avatar asked Aug 18 '14 20:08

boop


People also ask

How do you flag an enum?

The "|=" operator actually adds a flag to the enum, so the enum now contains two flag bits. You can use "|=" to add bits, while & will test bits without setting them. And Bitwise AND returns a value with 1 in the targeted bit if both values contain the bit.

What is the role of flag attribute in enum?

The [Flag] attribute is used when Enum represents a collection of multiple possible values rather than a single value. All the possible combination of values will come. The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value.

What are .NET enumerations?

An enumeration is a set of named integer constants. An enumerated type is declared using the enum keyword. C# enumerations are value data type. In other words, enumeration contains its own values and cannot inherit or cannot pass inheritance.


1 Answers

Simple, use the binary "or" operator:

BiomeType bType = BiomeType.Hot | BiomeType.Dry;

Also, if the values can be combined like this it's best to mark the enum with the Flags attribute to indicate this:

[Flags]
public enum BiomeType {
    Warm = 1,
    Hot = 2,
    Cold = 4,
    Intermediate = 8,
    Dry = 16,
    Moist = 32,
    Wet = 64,
}

Adding enumeration values is bad for a number of reasons. It makes it easy to produce a value that is outside the defined values, i.e.:

BiomeType bType = (BiomeType)((byte)BiomeType.Wet + (byte)BiomeType.Wet);

While contrived, this example yields a value of 128, which doesn't map to a known value. This will still compile and run, but it's likely you didn't build your code to handle values outside of those defined and could lead to undefined behavior. However, if you use the pipe (or "binary or") operator:

BiomeType bType = BiomeType.Wet | BiomeType.Wet;

The result is still just BiomeType.Wet.

Furthermore, using addition like in your question provides no Intellisense in the IDE which makes using the enumeration unnecessarily more difficult.

like image 62
Patrick Quirk Avatar answered Oct 27 '22 03:10

Patrick Quirk