Каков предпочтительный способ преобразования Enum в String в .NET 3.5?
- Enum.GetName
- Enum.Format
- ToString
Почему я должен отдавать предпочтение одному из них над другими? Лучше ли работает?
Каков предпочтительный способ преобразования Enum в String в .NET 3.5?
Почему я должен отдавать предпочтение одному из них над другими? Лучше ли работает?
С С# 6 лучшим способом получить имя перечисления является новый оператор nameof
:
nameof(MyEnum.EnumValue);
// Ouputs
> "EnumValue"
Это работает во время компиляции с заменой перечисления на строку в скомпилированном результате, что, в свою очередь, означает, что это самый быстрый способ.
Любое использование имен перечислений влияет на обфускацию кода, если вы считаете, что обфускация имен перечислений является полезной или важной - это, вероятно, целый другой вопрос.
Работает для нашего проекта...
public static String convertToString(this Enum eff)
{
return Enum.GetName(eff.GetType(), eff);
}
public static EnumType converToEnum<EnumType>(this String enumValue)
{
return (EnumType) Enum.Parse(typeof(EnumType), enumValue);
}
Все это внутренне в конечном итоге вызывает метод под названием InternalGetValueAsString
. Разница между ToString
и GetName
заключалась бы в том, что GetName
должен сначала проверить несколько вещей:
GetType
для значения, чтобы проверить это. .ToString
не нужно беспокоиться ни о какой из этих вышеперечисленных проблем, потому что он вызывает экземпляр самого класса, а не переданный в версии, поэтому из-за того, что .ToString
метод не имеет одинаковых вопросов проверки, как статические методы, я бы сделал вывод, что .ToString
- это самый быстрый способ получить значение в виде строки.
Я могу найти этот несвязанный вопрос в MSDN, который содержит фрагмент XML, который отвечает на этот вопрос. Любой из этих методов имеет один и тот же недостаток: они вызывают enum.toString()
, что не работает должным образом при использовании Dotfuscation. Другие проблемы, по-видимому, связаны с косвенным боксом (GetName и Format). К сожалению, я не могу найти никаких причин для использования любого из вышеперечисленных.
Перефразируя из фрагмент xml,
Передача коробочного перечисления в string.Format() или любая другая функция может привести к вызову
enum.toString()
. Это вызовет проблемы при Dotfuscating. Вы не должны использоватьenum.toString()
,enum.GetNames()
,enum.GetName()
,enum.Format()
илиenum.Parse()
для преобразования перечисления в строку. Вместо этого используйте оператор switch, а также при необходимости интернационализируйте имена.
В моих тестах Enum.GetName
выполнялся быстрее и прилично. Внутренне ToString
вызывает Enum.GetName
. Из источника для .NET 4.0 необходимо:
public override String ToString()
{
return Enum.InternalFormat((RuntimeType)GetType(), GetValue());
}
private static String InternalFormat(RuntimeType eT, Object value)
{
if (!eT.IsDefined(typeof(System.FlagsAttribute), false))
{
String retval = GetName(eT, value); //<== the one
if (retval == null)
return value.ToString();
else
return retval;
}
else
{
return InternalFlagsFormat(eT, value);
}
}
Я не могу сказать, что это причина для уверенности, но тесты утверждают, что один быстрее, чем другой. Оба вызова связаны с боксом (на самом деле это призывы к отражению, вы, по сути, извлекаете имена полей) и могут быть медленными по своему вкусу.
Настройка тестирования: перечисление с 8 значениями, нет. итераций = 1000000
Результат: Enum.GetName = > 700 мс, ToString = > 2000 мс
Если скорость не заметна, мне будет все равно и используйте ToString
, так как она предлагает гораздо более чистый вызов. Контраст
Enum.GetName(typeof(Bla), value)
с
value.ToString()
Enum.GetName()
Format()
на самом деле просто обертка вокруг GetName()
с некоторыми функциями форматирования (точнее, InternalGetValueAsString()
). ToString()
в значительной степени совпадает с Format()
. Я думаю, что GetName()
- лучший вариант, поскольку он совершенно очевидно, что он делает для тех, кто читает исходный код.
Я создаю метод расширения "Описание" и присоединяю его к перечислению, чтобы я мог получить поистине удобное имя, включающее в себя пробелы и обложку. Мне никогда не нравилось использовать значение enum как отображаемый текст, потому что это то, что мы разработчики используем для создания более читаемого кода. Он не предназначен для отображения пользовательского интерфейса. Я хочу иметь возможность изменять пользовательский интерфейс, не переходя и не изменяя перечисления на всем протяжении.
Это самый элегантный метод, который предназначен для него.
var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);
Хотя я не вижу проблем с вызовом .ToString()
, поскольку он просто короче.
var enumValueString = MyEnum.MyValue.ToString();
С новым синтаксисом С# 6 вы можете использовать:
Я не знаю, что такое "предпочтительный" метод (попросите 100 человек и получите 100 разных мнений), но делайте то, что проще и что работает. GetName
работает, но требует гораздо больше нажатий клавиш. ToString()
похоже, делает работу очень хорошо.
Это тоже сработает.
List<string> names = Enum.GetNames(typeof(MyEnum)).ToList();
Простой: перечисление имен в список:
List<String> NameList = Enum.GetNames(typeof(YourEnumName)).Cast<string>().ToList()