В .NET Core и .NET> 4 есть универсальный метод разбора :
Enum.TryParse("Active", out StatusEnum myStatus);
Это также включает в себя новые встроенные out
переменные C # 7 , так что это делает try-parse, преобразование в явный тип enum и инициализирует + заполняет myStatus
переменную.
Если у вас есть доступ к C # 7 и последней версии .NET, это лучший способ.
Оригинальный ответ
В .NET это довольно некрасиво (до 4 или выше):
StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);
Я склонен упростить это с помощью:
public static T ParseEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
Тогда я могу сделать:
StatusEnum MyStatus = EnumUtil.ParseEnum<StatusEnum>("Active");
В комментариях предлагается один вариант - добавить расширение, которое достаточно просто:
public static T ToEnum<T>(this string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
StatusEnum MyStatus = "Active".ToEnum<StatusEnum>();
Наконец, вы можете захотеть использовать перечисление по умолчанию, если строка не может быть проанализирована:
public static T ToEnum<T>(this string value, T defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
T result;
return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}
Что делает этот вызов:
StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);
Тем не менее, я бы осторожно добавил такой метод расширения, string
поскольку (без управления пространством имен) он будет отображаться во всех случаях, string
независимо от того, содержат ли они перечисление или нет (поэтому 1234.ToString().ToEnum(StatusEnum.None)
будет допустимым, но бессмысленным). Часто лучше избегать загромождения основных классов Microsoft дополнительными методами, которые применяются только в очень специфических контекстах, если ваша команда разработчиков не очень хорошо понимает, что делают эти расширения.
Используйте
Enum.TryParse<T>(String, T)
(≥ .NET 4.0):Это можно еще больше упростить с помощью встроенного типа параметра в C # 7.0 :
источник
Parse
генерирует пояснительные исключения для того, что пошло не так с преобразованием (значение былоnull
пустым или не имело соответствующей константы перечисления), что намного лучше, чемTryParse
логическое возвращаемое значение (которое подавляет конкретную ошибку)var result = Enum.TryParse<System.DayOfWeek>("55", out var parsedEnum);
Обратите внимание, что производительность
Enum.Parse()
ужасна, потому что она реализована с помощью отражения. (То же самоеEnum.ToString
относится и к другому.)Если вам нужно преобразовать строки в Enums в чувствительном к производительности коде, лучше всего
Dictionary<String,YourEnum>
при запуске создать его и использовать для конвертации.источник
Вы ищете Enum.Parse .
источник
Вы можете использовать методы расширения сейчас:
И вы можете вызвать их по следующему коду (здесь
FilterType
это тип enum):источник
Так что, если у вас есть перечисление с именем настроение, это будет выглядеть так:
источник
BEWARE:
Enum.(Try)Parse()
принимает несколько аргументов, разделенных запятыми, и объединяет их с двоичным «или»|
. Вы не можете отключить это, и, по моему мнению, вы почти никогда не хотите этого.Даже если
Three
не определено,x
все равно получит значение int3
. Это еще хуже: Enum.Parse () может дать вам значение, которое даже не определено для enum!Я не хотел бы испытывать последствия пользователей, добровольно или невольно, запускающих это поведение.
Кроме того, как упоминалось другими, производительность не идеальна для больших перечислений, а именно линейна по числу возможных значений.
Я предлагаю следующее:
источник
Enum.(Try)Parse accepts multiple, comma-separated arguments, and combines them with binary 'or'
. Означает, что вы можете установить значения перечисления как степени 2, и у вас есть очень простой способ для анализа нескольких логических флагов, например. "UseSSL, NoRetries, Sync". На самом деле это, вероятно, то, для чего он был разработан.Enum.Parse твой друг:
источник
Вы можете расширить принятый ответ значением по умолчанию, чтобы избежать исключений:
Тогда вы называете это как:
Если значение по умолчанию не является enum, Enum.TryParse завершится ошибкой и выдаст исключение, которое перехватывается.
После многих лет использования этой функции в нашем коде во многих местах может быть полезно добавить информацию о том, что эта операция стоит производительности!
источник
defaultValue
тип возвращаемого значения и метод оба имеют типT
. Если типы различаются, вы получите ошибку времени компиляции: «невозможно преобразовать из« ConsoleApp1.Size »в« ConsoleApp1.Color »» или что-то еще из ваших типов.Мы не могли предположить совершенно достоверный ввод и пошли с этим вариантом ответа @ Keith:
источник
источник
Разбирает строку в TEnum без try / catch и без метода TryParse () из .NET 4.5
источник
Супер простой код с использованием TryParse:
источник
Мне нравится решение метода расширения ..
Здесь ниже моя реализация с тестами.
источник
==================== Полная программа ====================
источник
Я использовал класс (строго типизированная версия Enum с разбором и улучшением производительности). Я нашел его на GitHub, и он должен работать и для .NET 3.5. Он имеет некоторые накладные расходы памяти, поскольку он буферизует словарь.
Блог пост Enums - лучший синтаксис, улучшенная производительность и TryParse в NET 3.5 .
И код: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs
источник
Для производительности это может помочь:
источник
Я обнаружил, что здесь случай со значениями перечисления, которые имеют значение EnumMember, не рассматривался. Итак, поехали:
И пример этого перечисления:
источник
Вы должны использовать Enum.Parse, чтобы получить значение объекта из Enum, после этого вы должны изменить значение объекта на конкретное значение перечисления. Приведение к перечисляемому значению можно выполнить с помощью Convert.ChangeType. Пожалуйста, взгляните на следующий фрагмент кода
источник
Попробуйте этот образец:
В этом примере вы можете отправить каждую строку и установить свой
Enum
. Если у васEnum
есть данные, которые вы хотели, верните их как вашEnum
тип.источник
newModel
каждую строку, поэтому, если она содержит тире, она не будет заменена. Кроме того, вам не нужно проверять, содержит ли строка что-либо, вы всеReplace
равно можете просто позвонить :var newModel = model.Replace("-", "").Replace(" ", "");
Не уверен, когда это было добавлено, но в классе Enum теперь есть
Parse<TEnum>(stringValue)
Используется примерно так с примером в вопросе:
var MyStatus = Enum.Parse<StatusEnum >("Active")
или игнорирование корпуса:
var MyStatus = Enum.Parse<StatusEnum >("active", true)
Вот декомпилированные методы, которые это использует:
источник
источник
источник
Если имя свойства отличается от того, что вы хотите назвать (т.е. языковые различия), вы можете сделать это следующим образом:
MyType.cs
EnumExtensions.cs
Program.cs
источник