Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if enum is in one of desired states

Tags:

c#

enums

If I have enum

    [Flags]
    public enum GameFlow
    {
        Normal = 1,
        NormalNoMove = 2,
        Paused = 4,
        Battle = 8
    }

Is it possible to check if the enum is in either one of desired states with a single check? For example if I'd like to check if enum's is either Normal or NormalNoMove do I always have to write it like this?

if(Flow == GameFlow.Normal || Flow == GameFlow.NormalNoMove)

It's not a big problem if there are only two values but there will be more enum states and it would be nice if I only would have to change it in one place. Is it somehow possible to make an enum alias that would return true if enum value is either Normal or NormalNoMove? Or do I have to write some kind of helper method to achive that(extension method?)

like image 497
kasztelan Avatar asked Aug 01 '13 18:08

kasztelan


People also ask

How do you know if an enum is present?

toList(). contains(""); (Suppose your enum is called E.) Here inside "" you should put a name of an enum constant for which you wish to check if it is defined in the enum or not.

Is enum stored in heap?

The enum itself, including its reference field, will live on the stack, while the referent will live on the heap.

How do you check if an enum contains a given string?

The EnumUtils class has a method called isValidEnum which takes as parameters the name of the Enum class and the String to be matched. It returns a boolean true if the String is contained in the Enum class, and a boolean false otherwise.

How do you check if a string is part of an enum C#?

In C#, we can check the specific type is enum or not by using the IsEnum property of the Type class. It will return true if the type is enum.


2 Answers

Maybe it can be useful

public static class EnumExtensions
{
    public static bool IsOneOf(this Enum enumeration, params Enum[] enums)
    {
        return enums.Contains(enumeration);
    }
}

// usage:
if(Flow.IsOneOf(GameFlow.Normal, GameFlow.NormalNoMove))
like image 74
DCharodey Avatar answered Oct 10 '22 13:10

DCharodey


Bitwise logic should work on flag enums like this.

if((Flow & (GameFlow.Normal | GameFlow.NormalNoMove)) > 0)

It's also possible to create enum values that combine other values, as I mention here.

So, in your case:

[Flags]
public enum GameFlow
{
    Normal = 1,
    NormalNoMove = 2,
    Paused = 4,
    Battle = 8,
    AnyNormal = Normal | NormalNoMove
}

bool IsNormal(GameFlow flow)
{
    return (flow & GameFlow.AnyNormal) > 0;
}

And a LINQPad test:

void Main()
{
    IsNormal(GameFlow.Normal).Dump();// True
    IsNormal(GameFlow.NormalNoMove).Dump();// True
    IsNormal(GameFlow.Paused).Dump();// False
    IsNormal(GameFlow.Battle).Dump();// False

    IsNormal(GameFlow.Normal | GameFlow.Paused).Dump();// True
    IsNormal(GameFlow.NormalNoMove  | GameFlow.Battle).Dump();// True
    IsNormal(GameFlow.Paused | GameFlow.Battle).Dump();// False
    IsNormal(GameFlow.Battle | GameFlow.Normal).Dump();// True

}

Based on your comment, I'm wondering if you should revise the bitwise flags here, too. It sounds like "Normal" is a state you want to check for, and "NormalNoMove" builds on that. Maybe your enum should look more like this:

[Flags]
public enum GameFlow
{
    Normal = 1,
    NormalNoMove = Normal | 2,
    Paused = 4,
    Battle = 8
}

That way, you can check whether flow & GameFlow.Normal > 0 to see if you're in either normal state: NormalNoMove just "extends" Normal, so to speak.

like image 20
StriplingWarrior Avatar answered Oct 10 '22 14:10

StriplingWarrior