Преобразование строки обратно в перечисление - PullRequest
4 голосов
/ 24 марта 2011

Есть ли более чистый и умный способ сделать это?

Я нажимаю на БД, чтобы получить данные для заполнения объекта, и преобразовываю строковое значение базы данных обратно в его перечисление (мы можем предположить, что все значения в базе данных действительно являются значениями в соответствующем перечислении)

Рассматриваемая строка - это строка ниже, которая устанавливает EventLog.ActionType ... причина, по которой я начал подвергать сомнению свой метод, заключается в том, что после знака равенства VS2010 продолжает пытаться переопределить то, что я печатаю, помещая это: "= EventActionType ("

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

...etc...

Ответы [ 5 ]

11 голосов
/ 24 марта 2011

Насколько я знаю, это лучший способ сделать это.Я установил служебный класс, чтобы обернуть эту функциональность методами, которые делают этот вид более чистым.

    /// <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>();
5 голосов
/ 24 марта 2011

Вы можете использовать методы расширения, чтобы придать некоторый синтаксический сахар вашему коду.Вы даже можете сделать это обобщение методов расширения.

Это код, о котором я говорю: 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 голосов
/ 24 марта 2011

Можно использовать метод расширения следующим образом:

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

И используйте это как:

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

Где Blah выше тип читателя [3].

0 голосов
/ 22 мая 2014

@ Ответ 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);
        }
    }
}

Extensions / 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);
        }
    }
}
0 голосов
/ 29 марта 2012

Вы можете получить любое значение перечисления, а не только EventActionType, как в вашем случае, с помощью метода followin.

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

Тогда вы можете вызвать его,

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

Этоэто более общий подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...