Конвертировать Enum в String - PullRequest
145 голосов
/ 27 января 2009

Какой способ преобразования Enum в строку является предпочтительным в .NET 3.5?

  • Enum.GetName
  • Enum.Format
  • ToString

Почему я должен предпочесть один из них другим? Кто-то работает лучше?

Ответы [ 12 ]

93 голосов
/ 31 июля 2015

Начиная с C # 6, лучший способ получить имя перечисления - это новый оператор nameof:

nameof(MyEnum.EnumValue);

// Ouputs
> "EnumValue"

Это работает во время компиляции, при этом перечисление заменяется строкой в ​​скомпилированном результате, что, в свою очередь, означает, что это самый быстрый способ.

Любое использование имен перечислений мешает запутыванию кода, если вы считаете, что запутывание имен перечислений стоит или важно - это, вероятно, совсем другой вопрос.

91 голосов
/ 10 декабря 2010

Работает для нашего проекта ...

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);
}
22 голосов
/ 11 июня 2013

В моих тестах 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()
21 голосов
/ 27 января 2009

Все они в конечном итоге вызывают метод с именем InternalGetValueAsString. Разница между ToString и GetName заключается в том, что GetName должен сначала проверить несколько вещей:

  1. Введенный вами тип не является нулевым.
  2. Тип, который вы ввели, фактически является перечислением.
  3. Значение, которое вы передали, не равно нулю.
  4. Переданное вами значение относится к типу, который перечисление может фактически использовать в качестве своего базового типа, или к типу самого перечисления. Для проверки используется значение GetType.

.ToString не нужно беспокоиться ни об одной из перечисленных выше проблем, поскольку он вызывается для экземпляра самого класса, а не для переданной версии, поэтому из-за того, что .ToString Метод не имеет тех же проблем с проверкой, что и статические методы. Я бы заключил, что .ToString - это самый быстрый способ получить значение в виде строки.

16 голосов
/ 18 апреля 2013

Enum.GetName (...)

Это самый элегантный метод, который предназначен для него.

var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);

Хотя я не вижу проблем с вызовом .ToString(), так как он просто короче.

var enumValueString = MyEnum.MyValue.ToString();

С новым синтаксисом C # 6 вы можете использовать:

nameof(MyEnum.MyValue)
16 голосов
/ 27 января 2009

Лучшее, что я могу найти, это этот не связанный вопрос на MSDN , который содержит фрагмент XML, который отвечает на этот вопрос. Любой из этих методов имеет один и тот же недостаток: они вызывают enum.toString(), что не работает должным образом при использовании Dotfuscation . Другие проблемы, по-видимому, связаны с косвенным боксом (GetName и Format). К сожалению, я не могу найти никаких причин производительности для использования любого из вышеперечисленного.

Перефразирование из xml-фрагмента ,

Передача упакованного перечисления в string. Format () или любая другая функция может привести к вызову enum.ToString(). Это вызовет проблемы при расфокусировке. Вы не должны использовать enum.ToString(), enum.GetNames(), enum.GetName(), enum.Format() или enum.Parse() для преобразования enum в строку. Вместо этого используйте оператор switch, а также при необходимости интернационализируйте имена.

15 голосов
/ 27 января 2009

Enum.GetName()

Format() - это просто оболочка вокруг GetName() с некоторыми функциями форматирования (или, если быть точным, InternalGetValueAsString()). ToString() почти так же, как Format(). Я думаю, что GetName() - лучший вариант, поскольку совершенно очевидно, что он делает для любого, кто читает источник.

8 голосов
/ 27 января 2009

Я создаю метод расширения «Description» и присоединяю его к перечислению, чтобы я мог получить действительно удобное именование, включающее пробелы и регистр. Мне никогда не нравилось использовать само значение enum в качестве отображаемого текста, потому что это то, что мы разработчики используем для создания более читабельного кода. Он не предназначен для отображения пользовательского интерфейса. Я хочу иметь возможность изменять пользовательский интерфейс, не проходя и не меняя перечисления во всем.

6 голосов
/ 27 января 2009

Я не знаю, что такое «предпочтительный» метод (спросите 100 человек и получите 100 разных мнений), но делайте то, что проще и работает GetName работает, но требует гораздо больше нажатий клавиш. ToString(), кажется, делает работу очень хорошо.

0 голосов
/ 21 декабря 2017

Для поклонников VB:

EnumStringValue = System.Enum.GetName(GetType(MyEnum), MyEnumValue)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...