Я хочу написать функцию, которая может проверять заданное значение (переданное в виде строки) по возможным значениям enum
. В случае совпадения он должен вернуть экземпляр enum; в противном случае он должен вернуть значение по умолчанию.
Функция может не использовать внутри внутри try
/ catch
, что исключает использование Enum.Parse
, которое вызывает исключение при задании недопустимого аргумента.
Я хотел бы использовать что-то вроде TryParse
функции для реализации этого:
public static TEnum ToEnum<TEnum>(this string strEnumValue, TEnum defaultValue)
{
object enumValue;
if (!TryParse (typeof (TEnum), strEnumValue, out enumValue))
{
return defaultValue;
}
return (TEnum) enumValue;
}
Ответы:
Как говорили другие, вы должны реализовать свой собственный
TryParse
. Саймон Мурье предоставляет полную реализацию, которая обо всем позаботится.Если вы используете перечисления битовых полей (то есть флаги), вам также необходимо обрабатывать строку, например,
"MyEnum.Val1|MyEnum.Val2"
которая является комбинацией двух значений перечисления. Если вы просто вызоветеEnum.IsDefined
эту строку, она вернет false, даже еслиEnum.Parse
обработает ее правильно.Обновить
Как упомянули Лиза и Кристиан в комментариях,
Enum.TryParse
теперь доступен для C # в .NET4 и выше.Документы MSDN
источник
Enum.IsDefined сделает все возможное. Это может быть не так эффективно, как, вероятно, было бы TryParse, но оно будет работать без обработки исключений.
Стоит отметить:
TryParse
в .NET 4.0 был добавлен метод.источник
GetNames
. Внутренне все эти методы (в том числеParse
) используют тоGetHashEntry
, что делает собственное отражение - один раз. На стороне яркой, .NET 4.0 имеет TryParse, и это родовое тоже :)Вот кастомная реализация
EnumTryParse
. В отличие от других распространенных реализаций, он также поддерживает перечисление, отмеченноеFlags
атрибутом.источник
Activator.CreateInstance(type)
для создания значения перечисления по умолчанию, а неEnum.ToObject(type, 0)
. Дело вкуса?В конце концов, вы должны реализовать это
Enum.GetNames
:Дополнительные замечания:
Enum.TryParse
включен в .NET 4. См. здесь http://msdn.microsoft.com/library/dd991876(VS.100).aspxEnum.Parse
исключение, возникающее при сбое. Это может быть быстрее при обнаружении совпадения, но, скорее всего, будет медленнее, если нет. В зависимости от данных, которые вы обрабатываете, это может быть или не быть чистым улучшением.РЕДАКТИРОВАТЬ: только что видел лучшую реализацию, которая кэширует необходимую информацию: http://damieng.com/blog/2010/10/17/enums-better-syntax-improved-performance-and-tryparse-in-net- 3-5
источник
Flags
атрибутом.На основе .NET 4.5
Пример кода ниже
Ссылка: http://www.dotnetperls.com/enum-parse
источник
У меня есть оптимизированная реализация, которую вы можете использовать в UnconstrainedMelody . Фактически, он просто кеширует список имен, но делает это красивым, строго типизированным и обобщенно ограниченным способом :)
источник
...
источник
В настоящее время нет готового Enum.TryParse. Это было запрошено в Connect (по- прежнему нет Enum.TryParse ), и был получен ответ, указывающий на возможное включение в следующую структуру после .NET 3.5. На данный момент вам нужно будет реализовать предлагаемые обходные пути.
источник
Единственный способ избежать обработки исключений - использовать метод GetNames (), и все мы знаем, что исключениями нельзя злоупотреблять для общей логики приложения :)
источник
Допустимо ли кеширование динамически генерируемой функции / словаря?
Поскольку вы (кажется) не знаете заранее тип перечисления, первое выполнение может сгенерировать то, чем могут воспользоваться последующие исполнения.
Вы даже можете кэшировать результат Enum.GetNames ()
Вы пытаетесь оптимизировать процессор или память? Вам действительно нужно?
источник
Как уже говорили другие, если вы не используете Try & Catch, вам нужно использовать IsDefined или GetNames ... Вот несколько примеров ... они в основном все одинаковые, первый обрабатывает перечисления, допускающие значение NULL. Я предпочитаю второй, поскольку он является расширением строк, а не перечислений ... но вы можете смешивать их, как хотите!
источник
Нет TryParse, потому что тип Enum неизвестен до времени выполнения. TryParse, который следует той же методологии, что и метод Date.TryParse, вызовет ошибку неявного преобразования для параметра ByRef.
Предлагаю сделать что-то вроде этого:
источник
Try
методов, результаты которых могут быть типами значений или гдеnull
может быть допустимый результат (например,Dictionary.TryGetValue, which has both such traits), the normal pattern is for a
метод Try` для возвратаbool
и передачи результата в качествеout
параметра. Для тех, которые возвращают типы классов, гдеnull
не является допустимым результатом, нет проблем с использованиемnull
return для обозначения отказаВзгляните на сам класс Enum (struct?). Для этого есть метод Parse, но я не уверен насчет трипарса.
источник
Этот метод преобразует тип перечисления:
Он проверяет базовый тип и сравнивает имя с ним для анализа. Если ничего не получится, он вернет значение по умолчанию.
источник