关于c#:Enum.Parse(),肯定是一个更简洁的方式?

Enum.Parse(), surely a neater way?

假设我有一个枚举,

1
2
3
4
5
public enum Colours
{
    Red,
    Blue
}

分析它们的唯一方法是:

1
2
string colour ="Green";
var col = (Colours)Enum.Parse(typeOf(Colours),colour);

这将引发System.ArgumentException,因为"green"不是Colours枚举的成员。

现在我真的不喜欢在try/catch中包装代码,难道没有更好的方法可以做到这一点,而不需要我遍历每个Colours枚举,并对colour进行字符串比较吗?


首先使用Enum.IsDefined(),以避免在尝试/捕获中包装自己。它将返回一个布尔值,该值表示输入是否为该枚举的有效成员。


我相信4.0有Enum.Tryparse

否则,请使用扩展方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static bool TryParse<T>(this Enum theEnum, string valueToParse, out T returnValue)
{
    returnValue = default(T);
    int intEnumValue;
    if (Int32.TryParse(valueToParse, out intEnumValue))
    {
        if (Enum.IsDefined(typeof(T), intEnumValue))
        {
            returnValue = (T)(object)intEnumValue;
            return true;
        }
    }
    return false;
}


只需扩展Sky与.NET 4 Enum.Tryparse的链接<>,即

1
2
3
4
5
Enum.TryParse<TEnum>(
    string value,
    [bool ignoreCase,]
    out TEnum result
)

可使用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    enum Colour
    {
        Red,
        Blue
    }

    private void ParseColours()
    {
        Colour aColour;

        // IMO using the actual enum type is intuitive, but Resharper gives
        //"Access to a static member of a type via a derived type"
        if (Colour.TryParse("RED", true, out aColour))
        {
           // ... success
        }

        // OR, the compiler can infer the type from the out
        if (Enum.TryParse("Red", out aColour))
        {
           // ... success
        }

        // OR explicit type specification
        // (Resharper: Type argument specification is redundant)
        if (Enum.TryParse<Colour>("Red", out aColour))
        {
          // ... success
        }
    }

如果要分析"可信"枚举,则使用enum.parse()
"可信"是指,我知道它将永远是一个有效的枚举,而不会出错…永远!

但有时"你永远不知道你会得到什么",对于那些时候,你需要使用一个可以为空的返回值。因为.NET不提供这种内置的功能,所以您可以自己滚动。这是我的食谱:

1
2
3
4
5
6
7
8
public static TEnum? ParseEnum<TEnum>(string sEnumValue) where TEnum : struct
{
    TEnum eTemp;
    TEnum? eReturn = null;
    if (Enum.TryParse<TEnum>(sEnumValue, out eTemp) == true)
        eReturn = eTemp;
    return eReturn;
}

要使用此方法,请按如下方式调用:

1
eColor? SelectedColor = ParseEnum<eColor>("Red");

只需将此方法添加到用于存储其他常用实用程序函数的类中。


不,这个没有"不抛出"的方法(一个其他类拥有的la-triparse)。

但是,您可以轻松地编写自己的代码,以便将try-catch逻辑(或isDefined检查)封装到一个helper方法中,这样就不会污染您的应用程序代码:

1
2
3
4
5
6
7
8
9
public static object TryParse(Type enumType, string value, out bool success)
{
  success = Enum.IsDefined(enumType, value);
  if (success)
  {
    return Enum.Parse(enumType, value);
  }
  return null;
}