How do you convert a string into an enum?

How do you convert a string into an enum?

Rate This
  • Comments 35

I've come across the situation on a number of occasions when coding where I've wanted to convert from a string to an enum. In the Media Catalog sample, I resorted to one giant switch statement that has a case block for each string that returns an enum from it.

One of my colleagues came up with the answer yesterday; it's one of those methods that you can never find when you're looking for it, but once discovered it seems blindingly obvious:

   object Enum.Parse(System.Type enumType, string value, bool ignoreCase);

So you can write the following kind of code:

   enum Colour
   {
      Red,
      Green,
      Blue
   } 

   // ...
   Colour c = (Colour) Enum.Parse(typeof(Colour), "Red", true);
   Console.WriteLine("Colour Value: {0}", c.ToString());

   // Picking an invalid colour throws an ArgumentException. To
   // avoid this, call Enum.IsDefined() first, as follows:
   string nonColour = "Polkadot";

   if (Enum.IsDefined(typeof(Colour), nonColour))
      c = (Colour) Enum.Parse(typeof(Colour), nonColour, true);
   else
      MessageBox.Show("Uh oh!");

What a time saver - thanks, Simon!

Footnote: interestingly, whilst writing this up I noticed that Enum.IsDefined() doesn’t offer the ignoreCase parameter. If you don’t know whether the casing is right, it seems the only way to do the conversion is using the Parse method and catching the ArgumentException. That's not ideal, since it runs a lot slower. I wonder if this is a loophole in the design; no doubt someone like Brad could cast light on it...

  • Do you have something similar to this in VB?
  • Venu, the old proverb says that it's better to teach a man to fish than to simply give him a fish, so I'm going to point you at an automated conversion tool from C# to VB:
    http://www.kamalpatel.net/ConvertCSharp2VB.aspx

    Simply copy and paste the code above into the tool, and you'll get the C# equivalent. Cool, isn't it?
  • You can get the string values of enums also by calling Enum.GetNames or Enum.GetName...
  • The problem occurs when the Enum definition is made of multiple words.

    Another more flexible approach (albeit much slower) is to adhorn each Enum value with a DescriptionAttribute, and to use reflection to grab that
  • Excellent! Like you said, glaringly obvious.
  • Great! That was exactly what I was looking for!
  • How about the C version of this...
    that would be really helpful...
  • Very helpful - Thanks!

    Can I get this in COBOL, 8088 assembly, and Pascal too? No hurry, I need it by next Wednesday.

    Thanks again!
  • Hi, i was just wondering if you knew how I could do this exact thing in C++.NET? I have found so many C# examples but they all seem so different to what I am used to.

    Many thanks,

    John
  • Well here's a small example using managed C++:

    namespace EnumMagic
    {
    public __gc class MagicSet
    {
    public:
    __value enum MagicItems
    {
     WAND
    , POINTY_HAT
    , RABBIT
    , SCARF
    , PLAYING_CARDS
    , PIDGEON
    };
    };
    }

    int _tmain()
    {
    String* aNewEnumString = __box( EnumMagic::MagicSet::PLAYING_CARDS )->ToString();

    EnumMagic::MagicSet* aNewMagicSet = new EnumMagic::MagicSet();

    if ( Enum::IsDefined( __typeof( EnumMagic::MagicSet::MagicItems ), S"RABBIT" ) )
    {
    aNewMagicSet =
    static_cast< EnumMagic::MagicSet* >( Enum::Parse( __typeof( EnumMagic::MagicSet::MagicItems ), S"RABBIT" ) );
    }

    if ( Enum::IsDefined( __typeof( EnumMagic::MagicSet::MagicItems ), S"PRETTY_ASSISTANT" ) )
    {
    aNewMagicSet =
    static_cast< EnumMagic::MagicSet* >( Enum::Parse( __typeof( EnumMagic::MagicSet::MagicItems ), S"PRETTY_ASSISTANT" ) );
    }

    return 0;
    }
  • genius.  cheers.  was just about to break out the giant switch.
  • The C# to VB.NET is great, but what about just plain VB or VBA?
  • Hi Tim:
    I wonder, if this can work in my situation.
    I have a switch statement:
    switch (moduleName)
    {
      case "Module1" : return 1; break;
      case "Module2" : reutrn 2; break;
    }

    I have also an enum:
    public enum ModuleNames
    {
       Module1,
       Module2
    }

    So is there a possibility I can substitute the "Module1", "Module2" in my switch with something like

    case ModuleNames.Module1: ....

    Also, in your line:
    Colour c = (Colour) Enum.Parse(typeof(Colour), "Red", true);
    Console.WriteLine("Colour Value: {0}", c.ToString());

    Why do we need to do so? I mean c.ToString() doesn't have the value of "Red"? So we already have it, Am I missing something?


    Thanks,
     
Page 1 of 3 (35 items) 123