190

I have an enumeration:

public enum MyColours
{
    Red,
    Green,
    Blue,
    Yellow,
    Fuchsia,
    Aqua,
    Orange
}

and I have a string:

string colour = "Red";

I want to be able to return:

MyColours.Red

from:

public MyColours GetColour(string colour)

So far i have:

public MyColours GetColours(string colour)
{
    string[] colours = Enum.GetNames(typeof(MyColours));
    int[]    values  = Enum.GetValues(typeof(MyColours));
    int i;
    for(int i = 0; i < colours.Length; i++)
    {
        if(colour.Equals(colours[i], StringComparison.Ordinal)
            break;
    }
    int value = values[i];
    // I know all the information about the matched enumeration
    // but how do i convert this information into returning a
    // MyColour enumeration?
}

As you can see, I'm a bit stuck. Is there anyway to select an enumerator by value. Something like:

MyColour(2) 

would result in

MyColour.Green
Matt Clarkson
  • 14,106
  • 10
  • 57
  • 85
  • 1
    possible duplicate of [How do I Convert a string to an enum in C#?](http://stackoverflow.com/questions/16100/how-do-i-convert-a-string-to-an-enum-in-c) – nawfal Jul 17 '14 at 09:04
  • 4
    @nawfal, didn't find that when I asked this all those years ago. Have voted to close as duplicate. – Matt Clarkson Jul 17 '14 at 09:10

13 Answers13

426

check out System.Enum.Parse:


enum Colors {Red, Green, Blue}

// your code:
Colors color = (Colors)System.Enum.Parse(typeof(Colors), "Green");

JMarsch
  • 21,484
  • 15
  • 77
  • 125
  • 84
    Don't forget you can have it ignore case sensitivity by passing in a third optional parameter to be "true" – Aerophilic Aug 07 '13 at 21:37
  • Exactly what I was looking for ! Cheers ! – Zame Oct 20 '17 at 10:08
  • 11
    @user1531040 Actually, there is an Enum.TryParse. – DarLom Nov 01 '17 at 21:14
  • 1
    Note that enum parsing always 'succeeds' if the input is numeric; it just returns the parsed number, which then get cast to the enum's type. So if you want to check if some user input is a valid enum or something else, you should check for numeric content first. Since it returns a valid enum but with a value that may not exist at all in the defined enum names, you can get some really weird problems. – Nyerguds Mar 03 '20 at 12:29
23

You can cast the int to an enum

(MyColour)2

There is also the option of Enum.Parse

(MyColour)Enum.Parse(typeof(MyColour), "Red")
Jeff Sternal
  • 47,787
  • 8
  • 93
  • 120
Guvante
  • 18,775
  • 1
  • 33
  • 64
21

Given the latest and greatest changes to .NET (+ Core) and C# 7, here is the best solution:

var ignoreCase = true;
Enum.TryParse("red", ignoreCase , out MyColours colour);

colour variable can be used within the scope of Enum.TryParse

Roman
  • 1,727
  • 1
  • 20
  • 28
5

All you need is Enum.Parse.

Bruno Brant
  • 8,226
  • 7
  • 45
  • 90
4
var color =  Enum.Parse<Colors>("Green");
pampi
  • 517
  • 4
  • 8
2

I marked OregonGhost's answer +1, then I tried to use the iteration and realised it wasn't quite right because Enum.GetNames returns strings. You want Enum.GetValues:

public MyColours GetColours(string colour)
{  
   foreach (MyColours mc in Enum.GetValues(typeof(MyColours))) 
   if (mc.ToString() == surveySystem) 
      return mc;

   return MyColors.Default;
}
Colin
  • 22,328
  • 17
  • 103
  • 197
1

You can use Enum.Parse to get an enum value from the name. You can iterate over all values with Enum.GetNames, and you can just cast an int to an enum to get the enum value from the int value.

Like this, for example:

public MyColours GetColours(string colour)
{
    foreach (MyColours mc in Enum.GetNames(typeof(MyColours))) {
        if (mc.ToString().Contains(colour)) {
            return mc;
        }
    }
    return MyColours.Red; // Default value
}

or:

public MyColours GetColours(string colour)
{
    return (MyColours)Enum.Parse(typeof(MyColours), colour, true); // true = ignoreCase
}

The latter will throw an ArgumentException if the value is not found, you may want to catch it inside the function and return the default value.

OregonGhost
  • 23,359
  • 7
  • 71
  • 108
1

Try this method.

public static class Helper
{
  public static T FromStr<T>(string str) where T : struct, System.Enum
    => System.Enum.TryParse<T>(value:str,ignoreCase:true,result:out var result)
    ? result
    : default;
  public static T? FromStrNull<T>(string str) where T : struct, System.Enum
    => System.Enum.TryParse<T>(value: str,ignoreCase: true,result: out var result)
    ? result
    : null;
}

And use it like this

var color = Helper.FromStr<MyColours>("red");
Waleed A.K.
  • 1,596
  • 13
  • 13
0

As mentioned in previous answers, you can cast directly to the underlying datatype (int -> enum type) or parse (string -> enum type).

but beware - there is no .TryParse for enums, so you WILL need a try/catch block around the parse to catch failures.

Addys
  • 2,461
  • 15
  • 24
  • 3
    Wasn't before this question was asked, but now there is as of .NET 4! http://msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx. It would be something like Enum.TryParse( "Red", out color ) – WienerDog May 10 '12 at 18:07
0
(MyColours)Enum.Parse(typeof(MyColours), "red", true); // MyColours.Red
(int)((MyColours)Enum.Parse(typeof(MyColours), "red", true)); // 0
Sandeep Shekhawat
  • 685
  • 1
  • 9
  • 19
0
class EnumStringToInt // to search for a string in enum
{
    enum Numbers{one,two,hree};
    static void Main()
    {
        Numbers num = Numbers.one; // converting enum to string
        string str = num.ToString();
        //Console.WriteLine(str);
        string str1 = "four";
        string[] getnames = (string[])Enum.GetNames(typeof(Numbers));
        int[] getnum = (int[])Enum.GetValues(typeof(Numbers));
        try
        {
            for (int i = 0; i <= getnum.Length; i++)
            {
                if (str1.Equals(getnames[i]))
                {
                    Numbers num1 = (Numbers)Enum.Parse(typeof(Numbers), str1);
                    Console.WriteLine("string found:{0}", num1);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Value not found!", ex);
        }
    }
}
Raja
  • 9
  • 2
0

One thing that might be useful to you (besides the already valid/good answers provided so far) is the StringEnum idea provided here

With this you can define your enumerations as classes (the examples are in vb.net):

< StringEnumRegisteredOnly(), DebuggerStepThrough(), ImmutableObject(True)> Public NotInheritable Class eAuthenticationMethod Inherits StringEnumBase(Of eAuthenticationMethod)

Private Sub New(ByVal StrValue As String)
  MyBase.New(StrValue)   
End Sub

< Description("Use User Password Authentication")> Public Shared ReadOnly UsernamePassword As New eAuthenticationMethod("UP")   

< Description("Use Windows Authentication")> Public Shared ReadOnly WindowsAuthentication As New eAuthenticationMethod("W")   

End Class

And now you could use the this class as you would use an enum: eAuthenticationMethod.WindowsAuthentication and this would be essentially like assigning the 'W' the logical value of WindowsAuthentication (inside the enum) and if you were to view this value from a properties window (or something else that uses the System.ComponentModel.Description property) you would get "Use Windows Authentication".

I've been using this for a long time now and it makes the code more clear in intent.

Ando
  • 11,199
  • 2
  • 30
  • 46
-1

You might also want to check out some of the suggestions in this blog post: My new little friend, Enum<T>

The post describes a way to create a very simple generic helper class which enables you to avoid the ugly casting syntax inherent with Enum.Parse - instead you end up writing something like this in your code:

MyColours colour = Enum<MyColours>.Parse(stringValue); 

Or check out some of the comments in the same post which talk about using an extension method to achieve similar.

Julian Martin
  • 194
  • 1
  • 4