Enum.Parse() or Switch

2019-04-21 01:01发布

For converting a string to an enum, which of the following ways is better?

  1. This code:

    colorEnum color = (colorEnum)Enum.Parse(typeof(colorEnum), "Green");
    
  2. or this:

    string colorString = ...
    colorEnum color;        
    switch (colorString)
    {
        case "Green":
            color = colorEnum.Green;
            break;
        case "Red":
            color = colorEnum.Red;
            break;
        case "Orange":
            color = colorEnum.Orange;
            break;
        ....
    }
    

11条回答
放荡不羁爱自由
2楼-- · 2019-04-21 01:21

You should use the Enum.TryParse, if it fails you can handle the error correctly.

sample:

     ColorsEnum colorValue; 
     if (Enum.TryParse(colorString, out colorValue))        
        if (Enum.IsDefined(typeof(Colors), colorValue) | colorValue.ToString().Contains(","))  
           Console.WriteLine("Converted '{0}' to {1}.", colorString, colorValue.ToString());
        else
           Console.WriteLine("{0} is not an underlying value of the Colors enumeration.", colorString);
     else
        Console.WriteLine("{0} is not a member of the Colors enumeration.", colorString);
查看更多
Emotional °昔
3楼-- · 2019-04-21 01:21

(Warning: includes plug for my own open source library...)

Personally I'd use Unconstrained Melody, which ends up with cleaner and more typesafe code:

ColorEnum color = Enums.ParseName<ColorEnum>(text);

You can use TryParseName if you suspect it may be invalid. Obviously this requires an extra library, but hopefully you'll find other things in there helpful too :)

Enum.TryParse from .NET 4 is better than the other built-in options, but:

  • You won't catch non-enum types at compile time, e.g. Enum.TryParse<int>(...) will still compile; Unconstrained Melody really only allows enum types
  • Enum.TryParse will also parse "1" (or whatever the numeric value is when converted to a string) - if you really only expect names, I think it's better to only accept names

I definitely wouldn't switch on the string values - it means if you rename the enum values, you've got to remember to rename the case value as well.

查看更多
相关推荐>>
4楼-- · 2019-04-21 01:21

1) Is much better. It's cleaner code. You are doing in one line what would take multiple in 2). Also, it's less bug prone. When you add another item to colorEnum, you would need to remember to extend 2) wheras 1) would just work.

You may also want some error handling on the Enum.Parse.

查看更多
萌系小妹纸
5楼-- · 2019-04-21 01:21

On a performance point of view, as enums are implemented as static fields, the parse method will probably ends up doing refection on then enum type and try a GetField method which might be faster than the case. On the other end, if 90% of the case, the color is green, the case will be very fast... Note that the CLR sometimes rearrange code internally, changing the order of the case based on statistic (actually, I'm not sure it does that but the doc claims it could).

查看更多
爷的心禁止访问
6楼-- · 2019-04-21 01:22

Personally, while I am totally fine with the Enum.Parse solution for non-performance scenarios (read: one off run of this function occasionally ... and there are many such scenarios to be sure), I can't countenance the thought of possibly involving some reflection type method when this function needs to be performed in a loop over hundreds/thousands plus enum values at once. Gack!

So the following is a solution that gets some of the best of both worlds.

Just retrieve all values of the enum at startup time or what not, whenever it works best for you (below is one way of doing that), and then construct a Dictionary with them.

    private static Dictionary<string, Color> colorDictionary;
    public static Dictionary<string, Color> ColorDictionary
    {
        get
        {
            if (colorDictionary== null) {
                colorDictionary = new Dictionary<string, Color>();
                var all = Enum.GetValues(typeof(Color)).OfType<Color>();
                foreach (var val in all)
                    dict.Add(val.ToString(), val);
            }
            return colorDictionary;
        }
    }
查看更多
登录 后发表回答