简体   繁体   English

将字符串转换回枚举

[英]Converting string back to enum

Is there a cleaner, more clever way to do this? 有更干净,更聪明的方法吗?

I'm hitting a DB to get data to fill an object and am converting a database string value back into its enum (we can assume that all values in the database are indeed values in the matching enum) 我正在使用数据库来获取数据以填充对象并将数据库字符串值转换回其枚举(我们可以假设数据库中的所有值都是匹配枚举中的值)

The line in question is the line below that sets EventLog.ActionType...the reason I began to question my method is because after the equals sign, VS2010 keeps trying to override what I'm typing by putting this: "= EventActionType(" 有问题的行是下面的行设置EventLog.ActionType ...我开始质疑我的方法的原因是因为在等号之后,VS2010一直试图通过放置这个来覆盖我正在键入的内容:“= EventActionType(”

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

...etc...

As far as I know, this is the best way to do it. 据我所知,这是最好的方法。 I've set up a utility class to wrap this functionality with methods that make this look cleaner, though. 我已经设置了一个实用程序类来使用使这看起来更干净的方法来包装此功能。

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

}

With these utility methods, you can just say: 使用这些实用方法,您可以说:

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

You can use extension methods to give some syntactic sugar to your code. 您可以使用扩展方法为您的代码提供一些语法糖。 You can even made this extension methods generics. 你甚至可以使这个扩展方法泛化。

This is the kind of code I'm talking about: http://geekswithblogs.net/sdorman/archive/2007/09/25/Generic-Enum-Parsing-with-Extension-Methods.aspx 这是我正在谈论的那种代码: 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);

Could use an extension method like so: 可以使用这样的扩展方法:

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

And use it like: 并使用它像:

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

Where Blah above is the type of reader[3]. 上面的Blah是读者的类型[3]。

@StriplingWarrior's answer didn't work at first try, so I made some modifications: @ StriplingWarrior的答案在第一次尝试时没有用,所以我做了一些修改:

Helpers/EnumParser.cs 助手/ 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);
        }
    }
}

Extensions/ParseEnumExtension.cs 扩展/ 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);
        }
    }
}

You could get any enum value back, not just EventActionType as in your case with the followin method. 您可以获得任何枚举值,而不仅仅是使用followin方法的EventActionType

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

You can call it then, 你可以打电话给,

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

This is a more generic approach. 这是一种更通用的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM