【问题标题】:Converting string back to enum将字符串转换回枚举
【发布时间】:2014-05-22 07:36:29
【问题描述】:

有没有更干净、更聪明的方法来做到这一点?

我正在访问数据库以获取数据以填充对象并将数据库字符串值转换回其枚举(我们可以假设数据库中的所有值确实是匹配枚举中的值)

有问题的行是下面设置 EventLog.ActionType 的行......我开始质疑我的方法的原因是因为在等号之后,VS2010 一直试图通过输入以下内容来覆盖我输入的内容:“= EventActionType("

using (..<snip>..)
{
  while (reader.Read())
  {
     // <snip>
     eventLog.ActionType = (EventActionType)Enum.Parse(typeof(EventActionType), reader[3].ToString());

...etc...

【问题讨论】:

    标签: c# enums


    【解决方案1】:

    据我所知,这是最好的方法。不过,我已经设置了一个实用程序类来包装此功能,并使用使此功能看起来更清晰的方法。

        /// <summary>
        /// Convenience method to parse a string as an enum type
        /// </summary>
        public static T ParseEnum<T>(this string enumValue)
            where T : struct, IConvertible
        {
            return EnumUtil<T>.Parse(enumValue);
        }
    
    /// <summary>
    /// Utility methods for enum values. This static type will fail to initialize 
    /// (throwing a <see cref="TypeInitializationException"/>) if
    /// you try to provide a value that is not an enum.
    /// </summary>
    /// <typeparam name="T">An enum type. </typeparam>
    public static class EnumUtil<T>
        where T : struct, IConvertible // Try to get as much of a static check as we can.
    {
        // The .NET framework doesn't provide a compile-checked
        // way to ensure that a type is an enum, so we have to check when the type
        // is statically invoked.
        static EnumUtil()
        {
            // Throw Exception on static initialization if the given type isn't an enum.
            Require.That(typeof (T).IsEnum, () => typeof(T).FullName + " is not an enum type.");
        }
    
        public static T Parse(string enumValue)
        {
            var parsedValue = (T)System.Enum.Parse(typeof (T), enumValue);
            //Require that the parsed value is defined
            Require.That(parsedValue.IsDefined(), 
                () => new ArgumentException(string.Format("{0} is not a defined value for enum type {1}", 
                    enumValue, typeof(T).FullName)));
            return parsedValue;
        }
    
        public static bool IsDefined(T enumValue)
        {
            return System.Enum.IsDefined(typeof (T), enumValue);
        }
    
    }
    

    使用这些实用方法,您可以说:

     eventLog.ActionType = reader[3].ToString().ParseEnum<EventActionType>();
    

    【讨论】:

    • 是的,我也是这么想的...可能是一些 Intellisense 怪异或扩展程序吓坏了,但就像我输入等号并继续值侧时,VS 会自动放置“EventActionType( “好像它试图将枚举视为一种正常的方法或其他东西......啊,好吧:)猜它可能只是每天让我烦恼的那些小事之一呵呵
    • 这真是太棒了......绝对会进入我的包里!谢谢
    • 我知道的老问题,但是 Require 是哪个命名空间的一部分?谷歌搜索 Require 命名空间会产生很多错误的结果。
    • @MattR: Require.That() => stackoverflow.com/questions/4892548/…
    【解决方案2】:

    您可以使用扩展方法为您的代码添加一些语法糖。您甚至可以将此扩展方法设为泛型。

    这就是我说的那种代码:http://geekswithblogs.net/sdorman/archive/2007/09/25/Generic-Enum-Parsing-with-Extension-Methods.aspx

      public static T EnumParse<T>(this string value)
      {
          return EnumHelper.EnumParse<T>(value, false);
      }
    
    
      public static T EnumParse<T>(this string value, bool ignoreCase)
      {
    
          if (value == null)
          {
              throw new ArgumentNullException("value");
          }
          value = value.Trim();
    
          if (value.Length == 0)
          {
    
              throw new ArgumentException("Must specify valid information for parsing in the string.", "value");
          }
    
          Type t = typeof(T);
    
          if (!t.IsEnum)
          {
    
              throw new ArgumentException("Type provided must be an Enum.", "T");
          }
    
          T enumType = (T)Enum.Parse(t, value, ignoreCase);
          return enumType;
      }
    
    
      SimpleEnum enumVal = Enum.Parse<SimpleEnum>(stringValue);
    

    【讨论】:

      【解决方案3】:

      可以使用这样的扩展方法:

      public static EventActionType ToEventActionType(this Blah @this) {
          return (EventActionType)Enum.Parse(typeof(EventActionType), @this.ToString());
      }
      

      并像这样使用它:

      eventLog.ActionType = reader[3].ToEventActionType();
      

      上面的 Blah 是阅读器的类型[3]。

      【讨论】:

        【解决方案4】:

        您可以取回任何枚举值,而不仅仅是EventActionType,就像您使用以下方法一样。

        public static T GetEnumFromName<T>(this object @enum)
        {
            return (T)Enum.Parse(typeof(T), @enum.ToString());
        }
        

        那你就可以调用了,

        eventLog.ActionType = reader[3].GetEnumFromName<EventActionType>()
        

        这是一种更通用的方法。

        【讨论】:

          【解决方案5】:

          @StriplingWarrior 的回答一开始没有用,所以我做了一些修改:

          Helpers/EnumParser.cs

          namespace MyProject.Helpers
          {
              /// <summary>
              /// Utility methods for enum values. This static type will fail to initialize 
              /// (throwing a <see cref="TypeInitializationException"/>) if
              /// you try to provide a value that is not an enum.
              /// </summary>
              /// <typeparam name="T">An enum type. </typeparam>
              public static class EnumParser<T>
                  where T : struct, IConvertible // Try to get as much of a static check as we can.
              {
                  // The .NET framework doesn't provide a compile-checked
                  // way to ensure that a type is an enum, so we have to check when the type
                  // is statically invoked.
                  static EnumParser()
                  {
                      // Throw Exception on static initialization if the given type isn't an enum.
                      if (!typeof (T).IsEnum)
                          throw new Exception(typeof(T).FullName + " is not an enum type.");
                  }
          
                  public static T Parse(string enumValue)
                  {
                      var parsedValue = (T)Enum.Parse(typeof (T), enumValue);
                      //Require that the parsed value is defined
                      if (!IsDefined(parsedValue))
                          throw new ArgumentException(string.Format("{0} is not a defined value for enum type {1}", 
                              enumValue, typeof(T).FullName));
          
                      return parsedValue;
                  }
          
                  public static bool IsDefined(T enumValue)
                  {
                      return Enum.IsDefined(typeof (T), enumValue);
                  }
              }
          }
          

          扩展/ParseEnumExtension.cs

          namespace MyProject.Extensions
          {
              public static class ParseEnumExtension
              {
                  /// <summary>
                  /// Convenience method to parse a string as an enum type
                  /// </summary>
                  public static T ParseEnum<T>(this string enumValue)
                      where T : struct, IConvertible
                  {
                      return EnumParser<T>.Parse(enumValue);
                  }
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2010-10-03
            • 1970-01-01
            • 1970-01-01
            • 2014-03-18
            • 2015-06-10
            • 1970-01-01
            • 2010-09-19
            • 1970-01-01
            相关资源
            最近更新 更多