About the author

Miron Abramson
Me
Software Engineer, Senior Developer at Rima, and .NET addicted for long time.

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Creative Commons License

Blog Flux Directory
Technology Blogs - Blog Top Sites

Another version for the missing method: Enum.TryParse (in C#)

The 'TryParse' methods for all types are very useful and I'm using them all the time. It's very surprising that Microsoft didn't include in the Framework a method that can be very useful: Enum.TryParse. A lot of coders find themself writing from time to time  'parsing' methods for their enums. Something like that:

public enum ImageType
{
    Jpg,
    Gif,
    Png
}

public static ImageType ParseImagetype(string typeName)
{
    typeName = typeName.ToLower();
    switch (typeName)
    {
        case "Gif":
            return ImageType.Gif;
        case "png":
            return ImageType.Png;
        default:
        case "jpg":
            return ImageType.Jpg;
    }
}...

 Thats work fine, but you need to write such 'parsing' method for each enum you have.  The Enum class have it's own 'parsing' method (that luckly have 'IgnoreCase' flag), but not a TryParse method. The commonly fix around is to put the Enum.Parse method inside Try & Catch, what is, of cource, give bad performance in case of failure. The Enum class have also a method 'IsDefined' that return an indication if a value is exists in the enum. unfortunately, this method doesn't have an  'IgnoreCase' flag.

So, trying to put all this 'knowledge' together, I wrote my own generic version for 'Enum.TryParse' method that is also ignore case and not using try & catch:

public static bool EnumTryParse<T>(string strType,out T result)
{
    string strTypeFixed = strType.Replace(' ', '_');
    if (Enum.IsDefined(typeof(T), strTypeFixed))
    {
        result = (T)Enum.Parse(typeof(T), strTypeFixed, true);
        return true;
    }
    else
    {
        foreach (string value in Enum.GetNames(typeof(T)))
        {
            if (value.Equals(strTypeFixed, StringComparison.OrdinalIgnoreCase))
            {
                result = (T)Enum.Parse(typeof(T), value);
                return true;
            }
        }
        result = default(T);
        return false;
    }
}

The line 'string strTypeFixed = strType.Replace(' ', '_');' is because I was getting the data from third party WebService that send the enum strings with spaces, what is not allowed in enum, so my enums had '_' instead of  spaces.

To parse a ImageType (from the example above) just use it like this:

ImageType type;
if (Utils.EnumTryParse<ImageType>(typeName, out type))
{
    return type;
}
return ImageType.Jpg;

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: C#
Posted by Miron on Saturday, March 08, 2008 8:54 AM
Permalink | Comments (8) | Post RSSRSS comment feed

Related posts

Comments

Joann

Saturday, March 08, 2008 3:48 PM

Joann

Can't you add it as an extension method in .NET 3.5?

Miron il

Sunday, March 09, 2008 11:06 AM

Miron

Hi Joann,
As far as I know (No too much experience with the extension methods, yet), the extension methods works with an instance of an object, and not on the type itself.
So, you will be able to do this: ImageType.Gif.TryParse()... but not this: Enum.TryParse()...
If I'm wrong, I will be glad to learn something new about the extension.

Juan ar

Sunday, March 09, 2008 11:48 PM

Juan

If I remember correctly (and I think I do at least for DateTime.TryParse), those methods use a try, a parse, and in the catch they return false... so I'd try to avoid them in projects where performance is an issue

Miron il

Monday, March 10, 2008 8:30 AM

Miron

You are absolutely wrong, Juan. All the TryParse methods are NOT using Try & Catch and the are much faster than Parse between Try Catch block.
They can really boost performance and safely to use.

Juan ar

Monday, March 10, 2008 9:16 AM

Juan

Hmm... you are right (I dissasembled the 2.0 assemblies to check), I don't really remember where I saw it, but it was a long time ago... maybe the first versions of the framework, or even the beta... but I'm sure I saw it because it caught my attention at the time...

Unknown us

Sunday, April 06, 2008 5:49 PM

Unknown

Is there a way to ensure that the type T is an enum?
unfortunately
where T:System.Enum
does not work.... any ideas?

Miron il

Sunday, April 06, 2008 10:23 PM

Miron

@Unknown,
Unfortunately, you right, and you cannot write 'where T:Enum'
What you can do to ensure the type is an Enum is something like that:
public static bool EnumTryParse<T>(string strType,out T result)
{
if (typeof(T).BaseType != typeof(System.Enum))
{
result = default(T);
return false;
}...
Or throw an exception...

Unknown us

Monday, April 07, 2008 3:40 AM

Unknown

yeah i realized that you can do typeof(T).IsEnum.....
the problem is that that will still compile, where as one of the main reasons to use generics is type safety at compile time....
Oh well, great method!
Thanks!

Add comment


(Will show your Gravatar icon)  

  Country flag





Live preview

Thursday, July 03, 2008 4:49 PM