Enum с человеческими именами

Проблема

Достаточно часто приходится использовать перечислимые типы (enum) для ограниченного набора значений. Они очень удобны для использования в коде, но возникают проблемы для вывода их на интерфейсную часть приложения. Не только в русском языке, но и в английском. Значения в перечислимом типе могут состоять логически из нескольких слов и неудобно их показывть в интерфейсе пользователя. Например:

Понятное дело, что показывать пользователю CompositeValue нехорошо. Гораздо лучше показать “Composite Value” (пробел появился). Или же перевести это на русский.

Было

Сейчас в коде можно встретить следующие монструозные конструкции:

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

Причем есть перечеслимый тип

А для формирования значений для вывода на экран используется свойство

Где опять же легко забыть указать новый тип.

Итого:

  • Очень много кода, где легко сделать ошибку, и разгрести все это достаточно тяжело будет.
  • Не очевидна связь значений типа и подписей человеческих.
  • Преобразования надо делать для каждого перечислимого типа.

Стало

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

Уже сразу видно, какое описание какому типу соответсвует.

Для того, чтобы получить значение из описания, необходимо использовать такой код:

Так как это неудобно писать каждый раз, то выделим в класс расширений.

Теперь можно писать

Уже гораздо легче и можно использовать для любого перечеслимого типа.

Для получения списка значений, код не сильно сложнее.

Использование:

Единственный минус, что использование через произвольное значение перечислимого типа.

Не хочется писать такой метод?

Использование прямо в рабочем коде.

Итог

На мой взгляд представленый способ более компактен и универсален. К тому же надо тестировать только одно место, все компактно.

  • Не надо боятся о прокидывании значений на интерфейс пользователя, так как все само появится.
  • Наглядность использования.
  • Размер кода уменьшается в разы

Исходный код с тестами прилагается.

Hard’n’Heavy!

2 комментарий на “Enum с человеческими именами

  1. Здравствуйте! Спасибо за статью.
    А как быть в приведенном Вами варианте с локализацией, хотелось бы иметь возможность брать строки («Не выбрано» и другие) из ресурсов, это возможно?
    public enum MyEnum {
    [Description(«Не выбрано»)]
    None,

    [Description(«Составное значение»)]
    CompositeValue,

    [Description(«Значение»)]
    Single
    }
    C уважением, Анна.

    • Добрый день, Анна!
      Для локализации таких ресурсов лучше сделать свои собственные атрибуты, с фактически той же реализацией, что и Description.
      Приведенный пример, для представления идеи. В реальном проекте я бы не записывал так строки, а постарался обращаться ко всем строковым переменным через какие-либо переменные или идентификаторы. Тогда в обработчике можно будет обращаться к менеджеру ресурсов и получать нужный текст.
      На примере статьи http://msdn.microsoft.com/ru-ru/library/y99d1cd3.aspx можно сказать, что в последнем кусочке кода можно будет подставлять значение из тега Description.

      public static class EnumExtenders {
      public static string ToStringX(this Enum enumerate) {
      var type = enumerate.GetType();
      var fieldInfo = type.GetField(enumerate.ToString());
      var attributes = (DescriptionAttribute[]) fieldInfo.GetCustomAttributes(typeof (DescriptionAttribute), false);
      var strId = (attributes.Length > 0) ? attributes[0].Description : enumerate.ToString();

      // взято дальше из примера в статье
      ResourceManager LocRM = new ResourceManager(«WindowsApplication1.WinFormStrings»,typeof(Form1).Assembly);

      // после того как получили каким-либо образом менеджер ресурсов, то можно уже получать перевод
      return LocRM.GetString(strId);
      }
      }

      мне кажется что так должно сработать ;)

      Удачи и успехов!

Оставить комментарий