Поделиться через


Разработка перечислений

Примечание.

Это содержимое перепечатывается разрешением Pearson Education, Inc. из руководства по проектированию платформы: соглашения, идиомы и шаблоны для повторно используемых библиотек .NET, 2-го выпуска. Этот выпуск был опубликован в 2008 году, и книга с тех пор была полностью пересмотрена в третьем выпуске. Некоторые сведения на этой странице могут быть устаревшими.

Перечисления — это особый тип значения. Существует два типа перечислений: простые перечисления и перечисления флагов.

Простые перечисления представляют небольшие закрытые наборы вариантов. Типичным примером простого перечисления является набор цветов.

Перечисления флагов предназначены для поддержки побитовых операций со значениями перечисления. Типичным примером перечисления флагов является список параметров.

✔️ Используйте перечисление для строгого типа параметров, свойств и возвращаемых значений, представляющих наборы значений.

✔️ Do благоприязать использовать перечисление вместо статических констант.

❌ Не используйте перечисление для открытых наборов (например, версию операционной системы, имена друзей и т. д.).

❌ НЕ предоставляйте зарезервированные значения перечисления, предназначенные для дальнейшего использования.

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

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

Распространенная практика обеспечения дальнейшего расширения API C заключается в добавлении зарезервированных параметров для подписей методов. Такие зарезервированные параметры можно выразить как перечисления с одним значением по умолчанию. Это не должно быть сделано в управляемых API. Перегрузка метода позволяет добавлять параметры в будущие выпуски.

❌ НЕ включать значения sentinel в перечисления.

Хотя они иногда полезны для разработчиков платформы, значения sentinel запутаны для пользователей платформы. Они используются для отслеживания состояния перечисления, а не одного из значений из набора, представленного перечислением.

✔️ Do предоставляет значение нуля для простых перечислений.

Рассмотрите возможность вызова значения, например "Нет". Если такое значение не подходит для конкретного перечисления, наиболее распространенное значение по умолчанию для перечисления должно быть назначено базовое значение нуля.

✔️ Рассмотрите возможность использования Int32 (по умолчанию в большинстве языков программирования) в качестве базового типа перечисления, если ни одно из следующих значений не имеет значения true:

  • Перечисление представляет собой перечисление флагов, и у вас более 32 флагов или ожидается, что в будущем будет больше.

  • Базовый тип должен отличаться от Int32 взаимодействия с неуправляемыми кодами, ожидающими перечисления разных размеров.

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

    • Вы ожидаете, что перечисление будет использоваться в качестве поля в очень часто созданной структуре или классе.

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

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

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

✔️ Флаг имени DO перечисления с множественными существительными или существительными фразами и простыми перечислениями с уникальными существительными или существительными фразами.

❌ Не расширяйте System.Enum напрямую.

System.Enum — это специальный тип, используемый средой CLR для создания определяемых пользователем перечислений. Большинство языков программирования предоставляют элемент программирования, который предоставляет доступ к этой функции. Например, в C# enum ключевое слово используется для определения перечисления.

Проектирование перечисления флагов

✔️ Примените к перечислениям System.FlagsAttribute флагов. Не применяйте этот атрибут к простым перечислениям.

✔️ Используйте две силы для значений перечисления флага, чтобы они могли свободно объединяться с помощью побитовой операции OR.

✔️ Рассмотрите возможность предоставления специальных значений перечисления для часто используемых сочетаний флагов.

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

❌ Избегайте создания перечислений флагов, в которых определенные сочетания значений недопустимы.

❌ Избегайте использования значений перечисления флага нулевого значения, если значение не представляет "все флаги очищаются" и называется соответствующим образом, как указано в следующем руководстве.

✔️ Do name the zero value of flag enums None. Для перечисления флага значение всегда должно означать "все флаги очищаются".

Добавление значения в перечисления

Очень часто обнаруживается, что необходимо добавить значения в перечисление после того, как вы уже отправили его. Существует потенциальная проблема совместимости приложений, когда добавленное значение возвращается из существующего API, так как плохо написанные приложения могут неправильно обрабатывать новое значение.

✔️ Рассмотрите возможность добавления значений в перечисления, несмотря на небольшой риск совместимости.

Если у вас есть реальные данные о несовместимости приложений, вызванных добавлением перечисления, рассмотрите возможность добавления нового API, возвращающего новые и старые значения, и отмените старый API, который должен продолжать возвращать только старые значения. Это обеспечит совместимость существующих приложений.

Фрагменты: © Корпорация Майкрософт (Microsoft Corporation), 2005, 2009. Все права защищены.

Перепечатано с разрешения Pearson Education, Inc. из книги Инфраструктура программных проектов. Соглашения, идиомы и шаблоны для многократно используемых библиотек .NET (2-е издание), авторы: Кржиштоф Цвалина (Krzysztof Cwalina) и Брэд Абрамс (Brad Abrams). Книга опубликована 22 октября 2008 г. издательством Addison-Wesley Professional в рамках серии, посвященной разработке для Microsoft Windows.

См. также