72

I have an enum

enum myEnum2 { ab, st, top, under, below}

I would like to write a function to test if a given value is included in myEnum

something like that:

private bool EnumContainValue(Enum myEnum, string myValue)
{
     return Enum.GetValues(typeof(myEnum))
                .ToString().ToUpper().Contains(myValue.ToUpper()); 
}

But it doesn't work because myEnum parameter is not recognized.

Echilon
  • 10,064
  • 33
  • 131
  • 217
Fred Smith
  • 2,047
  • 3
  • 25
  • 36

10 Answers10

109

Why not use

Enum.IsDefined(typeof(myEnum), value);

BTW it's nice to create generic Enum<T> class, which wraps around calls to Enum (actually I wonder why something like this was not added to Framework 2.0 or later):

public static class Enum<T>
{
    public static bool IsDefined(string name)
    {
        return Enum.IsDefined(typeof(T), name);
    }

    public static bool IsDefined(T value)
    {
        return Enum.IsDefined(typeof(T), value);
    }

    public static IEnumerable<T> GetValues()
    {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }
    // etc
}

This allows to avoid all this typeof stuff and use strongly-typed values:

Enum<StringSplitOptions>.IsDefined("None")
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • 1
    why not make the methods generic instead of class? Nice little extension methods would have been great.. – nawfal Nov 14 '12 at 09:08
  • @nawfal non-generic `Enum` class already exist in C#. Also for me `Enum.GetValues()` is a little more readable than `Enum.GetValues()` – Sergey Berezovskiy Nov 14 '12 at 09:26
  • 1
    I agree `Enum.GetValues()` is more readable,but `Enum.GetValues()` is what's seen in framework mostly & hence the latter feels at home.Like `Enum.TryParse<>` or `Tuple.Create<>`.May be because on a static class `Enum`,the validity of `T` is just for the static method you're calling on it,hence a more logical constraint has to be on the method,not the class.Also a constraint on class level feels a lil' redundant when the scope is limited just to a (subsequent, static) method call.With `Enum.GetValues()` the intent is quite clear. – nawfal Jan 29 '13 at 21:18
  • 1
    Personally I like `Enum.GetValues()` better, its just that its hardly seen in the framework.. – nawfal Jan 29 '13 at 21:20
  • 1
    @lazyberezovsky can you add a `where T : struct, IComparable, IFormattable, IConvertible` constraint on `T`? Will be nice. – nawfal Aug 12 '13 at 09:32
  • 1
    Nowadays you can constrain like so: `where T : Enum` – AnorZaken Mar 04 '20 at 10:36
  • Putting the generics on the type makes sense if you intend to store data in fields based on `T`, otherwise you are just giving the type-system more things to keep track of, whereas putting it on the method has the possibility of allowing type inference. So the best choice depends on what you want to do. Or you can of course use both if you need to store things *and* want type inference (the `Tuple` mentioned above being a nice example). – AnorZaken Mar 04 '20 at 10:42
64

No need to write your own:

    // Summary:
    //     Returns an indication whether a constant with a specified value exists in
    //     a specified enumeration.
    //
    // Parameters:
    //   enumType:
    //     An enumeration type.
    //
    //   value:
    //     The value or name of a constant in enumType.
    //
    // Returns:
    //     true if a constant in enumType has a value equal to value; otherwise, false.

    public static bool IsDefined(Type enumType, object value);

Example:

if (System.Enum.IsDefined(MyEnumType, MyValue))
{
    // Do something
}
LightStriker
  • 19,738
  • 3
  • 23
  • 27
12

just use this method

Enum.IsDefined Method - Returns an indication whether a constant with a specified value exists in a specified enumeration

Example

enum myEnum2 { ab, st, top, under, below};
myEnum2 value = myEnum2.ab;
 Console.WriteLine("{0:D} Exists: {1}", 
                        value, myEnum2.IsDefined(typeof(myEnum2), value));
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
4

What you're doing with ToString() in this case is to:

Enum.GetValues(typeof(myEnum)).ToString()... instead you should write:

Enum.GetValues(typeof(myEnum).ToString()...

The difference is in the parentheses...

3

Also can use this:

    enum myEnum2 { ab, st, top, under, below }
    static void Main(string[] args)
    {
        myEnum2 r;
        string name = "ab";
        bool result = Enum.TryParse(name, out r);
    }

The result will contain whether the value is contained in enum or not.

Akash Mehta
  • 2,779
  • 2
  • 15
  • 10
3
   public static T ConvertToEnum<T>(this string value)
    {
        if (typeof(T).BaseType != typeof(Enum))
        {
            throw new InvalidCastException("The specified object is not an enum.");
        }
        if (Enum.IsDefined(typeof(T), value.ToUpper()) == false)
        {
            throw new InvalidCastException("The parameter value doesn't exist in the specified enum.");
        }
        return (T)Enum.Parse(typeof(T), value.ToUpper());
    }
c-sharp
  • 573
  • 1
  • 9
  • 25
3

If your question is like "I have an enum type, enum MyEnum { OneEnumMember, OtherEnumMember }, and I'd like to have a function which tells whether this enum type contains a member with a specific name, then what you're looking for is the System.Enum.IsDefined method:

Enum.IsDefined(typeof(MyEnum), MyEnum.OneEnumMember); //returns true
Enum.IsDefined(typeof(MyEnum), "OtherEnumMember"); //returns true
Enum.IsDefined(typeof(MyEnum), "SomethingDifferent"); //returns false

If your question is like "I have an instance of an enum type, which has Flags attribute, and I'd like to have a function which tells whether this instance contains a specific enum value, then the function looks something like this:

public static bool ContainsValue<TEnum>(this TEnum e, TEnum val) where Enum: struct, IComparable, IFormattable, IConvertible
{
    if (!e.GetType().IsEnum)
        throw new ArgumentException("The type TEnum must be an enum type.", nameof(TEnum));

    dynamic val1 = e, val2 = val;
    return (val1 | val2) == val1;
}

Hope I could help.

florien
  • 487
  • 5
  • 16
2

Use the correct name of the enum (myEnum2).

Also, if you're testing against a string value you may want to use GetNames instead of GetValues.

Cristian Lupascu
  • 39,078
  • 16
  • 100
  • 137
2

just cast the enum as:

string something = (string)myEnum;

and now comparison is easy as you like

Talha
  • 18,898
  • 8
  • 49
  • 66
1

I think that you go wrong when using ToString().

Try making a Linq query

private bool EnumContainValue(Enum myEnum, string myValue)
{
    var query = from enumVal in Enum.GetNames(typeof(GM)).ToList()
                       where enumVal == myValue
                       select enumVal;

    return query.Count() == 1;
}
MaLKaV_eS
  • 1,325
  • 3
  • 23
  • 39