Сценарии, когда стоит привести enum к его значению - PullRequest
2 голосов
/ 05 марта 2012

У меня есть перечисления в одном из моих приложений Windows, как показано ниже:

private enum ModificationType
{
    Insert = 0,
    Update = 1,
    Delete = 2
}

У меня есть функция ниже:

private void UpdateDatabaseTransactions(ModificationType _modifcationType)
        {
int modType = (int)_modifcationType;
if (modType == 0) {...}
if (modType == 1) {...}
if (modType == 2) {...}

, также я могу использовать ее, как показано ниже:

if (_modifcationType == ModificationType.Insert) {...}
if (_modifcationType == ModificationType.Update) {...}
if (_modifcationType == ModificationType.Delete) {...}
}

В чем разница между обоими и в каких сценариях я должен типизировать значение и использовать, есть ли какие-либо средства повышения производительности при использовании любого из вышеперечисленных, или оба одинаковы?

Ответы [ 7 ]

6 голосов
/ 05 марта 2012

Что произойдет, если вы решите изменить перечисление ModificationType позже?Например:

private enum ModificationType
{
    Insert = 0,

    /* Oops, need a special insert type here */
    InsertSpecial = 1,

    Update = 2,
    Delete = 3
}

Это, по общему признанию, надуманный пример.(Но, конечно, это не невозможно - предположим, что ваш enum используется для ссылки на некоторую внешнюю зависимость, которая вносит критические изменения, скажем, в C API.)

Но если вы ссылаетесь на эти типы перечислений по значению, выдолжны отследить все ссылки на них.Вы хотите пройтись по своему коду, пытаясь выяснить, используется ли число 3 для ссылки на это перечисление или какую-то другую случайную константу?

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

Нет снижения производительности за использование ModificationType.Delete вместо 4, 5, 6 или любого другого.

4 голосов
/ 05 марта 2012

Сценарий, который я мог бы себе представить, вам нужно привести (из), если вы прочитаете _modifcationType извне вашего кода - то есть: из файла, базы данных, JSON и т. Д.

Кроме этого - I 'использовать его без приведения - особенно в блоке switch..case.

3 голосов
/ 05 марта 2012

Оба образца должны работать одинаково. Я бы предложил использовать второй из-за читабельности. Гораздо проще понять и поддерживать, чем первый.

3 голосов
/ 05 марта 2012

Они оба почти эквивалентны (при условии, что целочисленные значения, которые вы используете, фактически совпадают со значениями, которые вы используете в своем перечислении). Вы не заметите разницу в производительности между ними.

При этом вы должны использовать фактические значения Enum, когда это возможно. Весь смысл использования Enum состоит в том, чтобы давать целочисленные значения. Если кто-то новичок в кодовой базе смотрит на первый пример, он не узнает, что делает код. Если они посмотрят на второе, оно все равно будет иметь смысл.

3 голосов
/ 05 марта 2012

При сравнении экземпляра enum с конкретным значением вы всегда должны использовать именованные значения enum. Использование ModificationType.Insert намного более безопасно для редактирования / изменения, чем 0. Редактирование значения не повлияет на существующие сравнения с использованием ModificationType.Insert, но приведет к тому, что поведение функций, полагающихся на него, будет равно 0.

1 голос
/ 06 марта 2012

Используйте значения перечисления.Именованное значение перечисления, например, ваше ModificationType.Delete, является константой времени компиляции.

Если нет необходимости делать иначе:

  • Иметь значение по умолчанию перечисления(0) undefined или define как Unknown или что-то похожее:

    public enum ModificationType
    {
     [ Unknown = 0 , ]
     Insert = 1 ,
     Update = 2 ,
     Delete = 3 ,
    }
    
  • Когда вы делаете с ними что-то вроде ваших операторов if / then, используйте переключатель и бросаете InvalidOperationException или подобное исключение для значений вне диапазона.Это сохранит ваш бекон (или чей-то другой) вниз по линии, когда домен enum расширяется, или у вас есть ошибка, когда экземпляр enum неправильно инициализирован с правильным значением:

    switch ( someModificationType )
    {
    case ModificationType.Insert : performInsert() ; break ;
    case ModificationType.Delete : performDelete() ; break ;
    case ModificationType.Update : performUpdate() ; break ;
    default :
      throw new InvalidOperationException() ;
      break ;
    }
    

Одна из моих любимых ошибок в MS Word заключалась в том, чтобы что-то сделать словом, и встретила всплывающее окно MessageBox с кнопкой ОК и загадочным сообщением: «Это сообщение никогда не должно появляться».Не совсем полезно, но сердце разработчика было в нужном месте.

1 голос
/ 05 марта 2012

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

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