Почему переключатель для enums принимает неявное преобразование в 0, но нет для какого-либо другого целого?
Есть:
enum SomeEnum { A = 0, B = 1, C = 2 }
Теперь компилятор позволяет мне написать:
SomeEnum x = SomeEnum.A; switch(x) { case 0: // <--- Considered SomeEnum.A break; case SomeEnum.B: break; case SomeEnum.C: break; default: break; }
0
считается SomeItems.A
. Но я не могу написать:
- Java: если vs. Switch
- Оператор switch: по умолчанию должен быть последний случай?
- идея выбора переключателя / образца
- Почему оператор switch, а не if-else?
- Использовать «переход» в коммутаторе?
SomeEnum x = SomeEnum.A; switch(x) { case 0: break; case 1: // <--- Here is a compilation error. break; case SomeEnum.C: break; default: break; }
Почему существует только неявное преобразование для 0
?
- Почему Switch / Case, а не If / Else If?
- Почему оператор switch не может применяться к строкам?
- Использование NSString в операторе switch
- Есть ли лучшая альтернатива этому, чтобы «включить тип»?
- Почему переменные не могут быть объявлены в инструкции switch?
- Почему этот переключатель на корпусе типа считается запутанным?
- Тест для нескольких случаев в коммутаторе, например, OR (||)
- Зачем нам нужно прерывать заявления о случаях?
Из ECMA-334 (спецификация языка C #)
13.1.3. Неявные преобразования перечислений
Неявное преобразование перечислений позволяет преобразовать десятичный целочисленный литерал 0 в любой тип enums.
Значение по умолчанию enum равно 0
и во время компиляции известно, что это разрешено в инструкции switch. Для значения, отличного от 0
, во время компиляции не может быть определено, будет ли это значение существовать в перечислении или нет.
enum (ссылка C #)
Присвоение дополнительных значений новым версиям перечислений или изменению значений элементов enums в новой версии может вызвать проблемы для зависимого исходного кода. Часто бывает, что значения enums используются в операторах switch, и если к типу enums добавлены дополнительные элементы, тест по умолчанию может неожиданно вернуться к истине.
Я бы также добавил, что синтаксис с 0
вместо точного enum
в инструкции switch
может стать подверженным ошибкам. Рассмотрим следующий код:
enum TestEnum { NA = 0, A }
а потом
var e = TestEnum.NA; switch(e) { case 0: { break; } case TestEnum.A: { break; } }
Это компилируется и работает хорошо. Однако если по какой-либо причине декларация enum
изменяется на
enum TestEnum { NA = 1, A }
все сломается.
Хотя в большинстве ситуаций значение по умолчанию для enum
равно 0
и по этой причине этот синтаксис может иметь место, я бы использовал точное enum
.