【问题标题】:Enum.Parse(), surely a neater way?Enum.Parse(),肯定是一种更简洁的方式吗?
【发布时间】:2010-03-07 01:04:46
【问题描述】:

假设我有一个枚举,

public enum Colours
{
    Red,
    Blue
}

我能看到解析它们的唯一方法是执行以下操作:

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

这将抛出一个System.ArgumentException,因为“Green”不是Colours 枚举的成员。

现在我真的很讨厌在 try/catch 中包装代码,有没有更简洁的方法可以做到这一点,不涉及我遍历每个 Colours 枚举,并与 colour 进行字符串比较?

【问题讨论】:

    标签: c# asp.net enums


    【解决方案1】:

    首先使用Enum.IsDefined(),以免自己陷入try/catch。它将返回一个布尔值,判断输入是否是该枚举的有效成员。

    【讨论】:

    • 更要记住的是,字符串中的数字即使不在您的枚举中也会被解析!所以记得使用 TryParse 并检查 IsDefined 是否能抓住这个怪癖!
    【解决方案2】:

    我相信4.0有Enum.TryParse

    否则使用extension method:

    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;
    }
    

    【讨论】:

    • 这个 TryParse 与 4.0 TryParse 不同,valueToParse 必须是 (string)((byte)YourEnum.YourValue)),源使用它从 url 查询字符串中解析枚举数,不能使用它解析(字符串)YourEnum.YourValue
    • 此自定义方法public static bool TryParse&lt;T&gt;(this Enum theEnum, string valueToParse, out T returnValue) 需要添加泛型参数约束public static bool TryParse&lt;T&gt;(this Enum theEnum, string valueToParse, out T returnValue) where T : struct 例如
    【解决方案3】:

    只是为了扩展 Sky 到 .Net 4 Enum.TryParse<> 的链接,即

    Enum.TryParse<TEnum>(
        string value,
        [bool ignoreCase,]
        out TEnum result
    )
    

    可以这样使用:

        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
            }
        }
    

    【讨论】:

      【解决方案4】:

      不,没有“no-throw”方法可以解决这个问题(一些其他类有的 la TryParse)。

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

      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;
      }
      

      【讨论】:

        【解决方案5】:

        如果我正在解析“可信”枚举,那么我使用 Enum.Parse()。
        受信任”我的意思是,我知道它始终是一个有效的枚举,而不会出错......永远!

        但有时“你永远不知道你会得到什么”,在那些时候,你需要使用一个可以为空的返回值。由于 .net 不提供此功能,因此您可以自己动手。这是我的食谱:

        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;
        }
        

        要使用此方法,请像这样调用它:

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

        只需将此方法添加到您用来存储其他常用实用程序功能的类中。

        【讨论】:

          猜你喜欢
          • 2021-03-24
          • 2020-07-06
          • 2021-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-27
          • 1970-01-01
          相关资源
          最近更新 更多