Подтвердить что ты не робот

Общая версия Enum.Parse в С#

Я регулярно задавался вопросом, почему С# еще не выполнил Generic Enum.Parse

Скажем, у меня

enum MyEnum
{
   Value1,
   Value2
}

И из файла XML/DB я хочу создать Enum.

MyEnum val = (MyEnum)Enum.Parse(typeof(MyEnum), "value1", true);

Не удалось ли это реализовать как-то вроде

MyEnum cal = Enum.Parse<MyEnum>("value1");

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

Любые мысли?

4b9b3361

Ответ 1

Он уже реализован в .NET 4;) Посмотрите здесь.

MyEnum cal;
if (!Enum.TryParse<MyEnum>("value1", out cal))
   throw new Exception("value1 is not valid member of enumeration MyEnum");

Также обсуждение здесь содержит некоторые интересные моменты.

Ответ 2

И в желаемом синтаксисе вопроса:

MyEnum cal = Toolkit.Parse<MyEnum>("value1");

Примечание. Поскольку С# запрещает вам добавлять статические расширения, вы должны разместить эту функцию в другом месте. Я использую статический класс Toolkit, который содержит все эти полезные биты:

/// <summary>
/// Converts the string representation of the name or numeric value of one or
//  more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <typeparam name="TEnum">An enumeration type.</typeparam>
/// <param name="value">A string containing the name or value to convert.</param>
/// <returns>An object of type TEnum whose value is represented by value</returns>
/// <exception cref="System.ArgumentNullException">enumType or value is null.</exception>
/// <exception cref=" System.ArgumentException"> enumType is not an System.Enum. -or- 
/// value is either an empty string or only contains white space.-or- 
/// value is a name, but not one of the named constants defined for the enumeration.</exception>
/// <exception cref="System.OverflowException">value is outside the range of the underlying type of enumType.</exception>
public static TEnum Parse<TEnum>(String value) where TEnum : struct
{
   return (TEnum)Enum.Parse(typeof(TEnum), value);
}

Ответ 3

Хотя ограничение на System.Enum запрещено С#, оно разрешено в .NET, а С# может использовать типы или методы с такими ограничениями. См. Jon Skeet библиотека Unconstrained Melody, которая содержит код, который делает именно то, что вы хотите.

Ответ 4

public class EnumHelper
{
    public static T? TryParse<T>(string text)
        where T: struct
    {
        if (string.IsNullOrEmpty(text))
        {
            return null;
        }

        T r;

        if (Enum.TryParse<T>(text, out r))
        {
            return r;
        }

        return null;
    }
}

Ответ 5

Немного измененная версия ответа @ian-boyd, используя метод расширения, чтобы избежать необходимости указывать имя статического класса в вызове:

MyEnum cal = "value1".Parse<MyEnum>();

/// <summary>
/// Converts the string representation of the name or numeric value of one or
//  more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <typeparam name="TEnum">An enumeration type.</typeparam>
/// <returns>An object of type TEnum whose value is represented by value</returns>
/// <exception cref="System.ArgumentNullException">enumType or value is null.</exception>
/// <exception cref=" System.ArgumentException"> enumType is not an System.Enum. -or- 
/// value is either an empty string or only contains white space.-or- 
/// value is a name, but not one of the named constants defined for the enumeration.</exception>
/// <exception cref="System.OverflowException">value is outside the range of the underlying type of enumType.</exception>
public static TEnum Parse<TEnum>(this String value) where TEnum : struct
{
   return (TEnum)Enum.Parse(typeof(TEnum), value);
}

Ответ 6

Пока немного настраиваем некоторые методы, пытаясь создать нечто похожее на исходное предложение:

MyEnum cal = Enum.Parse<MyEnum>("value1");

мне показалось, что этот синтаксис невозможен в С#, так как тип Enum считается непустым.

Если мы вызываем метод "Enum.TryParse", передавая значение, не соответствующее элементу перечисления, значение "Enum" по умолчанию будет возвращено в переменной "out". Вот почему нам нужно тестировать сначала результат "Enum.TryParse", так как просто вызов

MyEnum cal;
Enum.TryParse<MyEnum>("value1", out cal);

и проверка значения "cal" не всегда даст надежный результат.