Универсальная версия Enum.Parse на C # - PullRequest
41 голосов
/ 11 февраля 2010

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

Допустим, у меня есть

enum MyEnum
{
   Value1,
   Value2
}

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

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

Разве это не могло быть реализовано как что-то вроде

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

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

Есть мысли?

Ответы [ 6 ]

36 голосов
/ 11 февраля 2010

Это уже реализовано в .NET 4;) Взгляните здесь .

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

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

16 голосов
/ 13 декабря 2012

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

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

Примечание : Так как C # запрещает вам добавлять статические расширения, вы должны разместить функцию в другом месте. я использую статический 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);
}
6 голосов
/ 11 февраля 2010

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

2 голосов
/ 23 декабря 2014
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;
    }
}
1 голос
/ 13 декабря 2015

Слегка измененная версия ответа @ 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);
}
0 голосов
/ 08 сентября 2013

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

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

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

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

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

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

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