Список const int вместо enum - PullRequest
       2

Список const int вместо enum

8 голосов
/ 08 сентября 2011

Я начал работать с большой базой кода C # и обнаружил использование статического класса с несколькими полями const. Этот класс действует точно так же, как перечисление.

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

Есть ли причина не использовать перечисления и использовать вместо них целочисленные значения? Вот как выглядит код:

public int FieldA { get; set; }
public int FieldB { get; set; }

public static class Ids
{
    public const int ItemA = 1;
    public const int ItemB = 2;
    public const int ItemC = 3;
    public const int ItemD = 4;
    public const int ItemE = 5;
    public const int ItemF = 6;
}

Однако я думаю, что вместо этого должно быть следующее:

public Ids FieldA { get; set; }
public Ids FieldB { get; set; }

Ответы [ 5 ]

6 голосов
/ 08 сентября 2011

Я думаю, что многие ответы здесь игнорируют последствия семантики enums.

  • Вы должны рассмотреть использование enum, когда весь наборвсе действительные значения (идентификаторы) известны заранее и достаточно малы, чтобы быть объявленными в программном коде.

  • Вы должны рассмотреть использование int, когда набор известных значений равен подмножество всех возможных значений - и код должен знать только об этом подмножестве.

Что касается рефакторинга - когда позволяют время и деловые ограничения, это хорошоИдея очистки кода, когда новый дизайн / реализация имеет явное преимущество по сравнению с предыдущей реализацией и когда риск хорошо понятен.В ситуациях, когда выгода низкая или риск высокий (или оба), может быть лучше занять позицию «не навреди» , а не «постоянно улучшать» .Только вы в состоянии судить, какое дело относится к вашей ситуации.

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

3 голосов
/ 08 сентября 2011

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

Есть несколько возможных причин для выбора enum или const-int для реализации, хотя я не могу придумать много сильных для реального примера, который вы 'Мы опубликовали - на первый взгляд, он кажется идеальным кандидатом для перечисления.

Вот несколько идей, которые приходят на ум:

Перечисления

  • Они обеспечивают безопасность типов.Вы не можете передать любое старое число, где требуется значение enum.
  • Значения могут быть автоматически сгенерированы
  • Вы можете использовать отражение, чтобы легко преобразовать между «значениями» и «именами»
  • Вы можете легко перечислить значения в перечислении в цикле, а затем, если вы добавите новые члены перечисления, цикл автоматически примет их во внимание.
  • Вы можете вставлять новые значения enunm, не беспокоясь о возникновении конфликтовесли вы случайно повторите значение.

const-ints

  • Если вы не понимаете, как использовать перечисления (например, не знаете, какизменить базовый тип данных перечисления, или как установить явные значения для значений перечисления, или как назначить одно и то же значение для нескольких констант), вы можете ошибочно полагать, что достигаете чего-то, для чего не можете использовать перечисление, используяconst.
  • Если вы привыкли к другим языкам, вы можете просто естественным образом подойти к проблеме с conts, не понимая, что существует лучшее решение.
  • Вы можете наследовать от классов, чтобы расширять их, но досадно, что вы не можете получить новое перечисление из существующего (что было бы действительно полезной функцией).Поэтому вы можете использовать класс (но не тот, что в вашем примере!) Для получения «расширяемого перечисления».
  • Вы можете легко передавать целые числа.Использование перечисления может потребовать от вас постоянного приведения (например) данных, которые вы получаете из базы данных в перечислимый тип и из него.То, что вы теряете в безопасности типов, вы получаете в удобстве.По крайней мере, до тех пор, пока вы не передадите неправильный номер куда-нибудь ...: -)
  • Если вы используете только чтение, а не const, значения сохраняются в реальных ячейках памяти, которые считываются при необходимости.Это позволяет публиковать константы в другой сборке, которые считываются и используются во время выполнения, а не встроены в другую сборку, что означает, что вам не нужно перекомпилировать зависимую сборку при изменении какой-либо из констант в вашей собственной сборке.Это важное соображение, если вы хотите иметь возможность исправлять большое приложение, просто выпуская обновления для одной или двух сборок.
  • Я думаю, это способ прояснить, что значения перечисления должны остаться без изменений.С помощью enum другой программист просто не задумываясь вводит новое значение, но список констант заставляет задуматься: «Почему это так? Как безопасно добавить новое значение?».Но я бы достиг этого, поместив явные значения в перечисления и добавив четкий комментарий, а не прибегая к концам.

Почему вы должны оставить реализацию в покое?

  • Код вполне мог быть написан идиотом, у которого нет веских оснований для того, что он сделал.Но изменение его кода и показ его, что он идиот, не является умным или полезным шагом.
  • Может быть, это хорошая причина, и вы что-то сломаете, если измените ее (например, может понадобитьсябыть классом из-за доступа через рефлексию, через внешние интерфейсы или из-за того, что люди не смогут легко сериализовать значения, потому что они будут нарушены используемой системой запутывания).Люди, которые не до конца понимают, как что-то работает, не вводят в системы ненужные ошибки, особенно если они не знают, как проверить свои изменения, чтобы убедиться, что они ничего не сломали.
  • Классможет быть автоматически сгенерирован внешним инструментом, так что это инструмент, который нужно исправить, а не исходный код.
  • Может быть, в будущем планируется сделать что-то еще с этим классом (?!)
  • Даже если изменение безопасно, вам придется повторно протестировать все, что затронуто изменением.Если код работает так, как есть, стоит ли выигрыш?При работе с унаследованными системами мы часто видим существующий код низкого качества или просто делаем то, что нам лично не нравится, и мы должны признать, что его «исправление» неэффективно с точки зрения затрат, независимо от того, насколько оно нудит.Конечно, вы также можете откусить назад: «Я же вам говорил!»когда реализация на основе const терпит неудачу из-за отсутствия безопасности типов.Но, кроме безопасности типов, реализация в конечном итоге не менее эффективна или действенна, чем enum.
1 голос
/ 08 сентября 2011

Если это не сломано, не исправляйте это.

Я не знаю проект системы, над которой вы работаете, но я подозреваю, что поля являются целыми числами, которые просто имеют ряд предопределенных значений. То есть они могут в каком-то будущем состоянии содержать больше, чем эти предопределенные значения. Хотя enum допускает этот сценарий (посредством приведения), это означает, что действительными являются только те значения, которые содержит перечисление.

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

0 голосов
/ 08 сентября 2011

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

Как в вызовах RPC или что-то ...

0 голосов
/ 08 сентября 2011

Да, это действительно помогает с читабельностью, и нет, я не могу придумать никаких причин против этого.

Использование const int - очень распространенная "старая школа" практики программирования для C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...