Почему переключатель для перечисления принимает неявное преобразование в 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
. Но я не могу написать:
SomeEnum x = SomeEnum.A;
switch(x)
{
case 0:
break;
case 1: // <--- Here is a compilation error.
break;
case SomeEnum.C:
break;
default:
break;
}
Почему существует только неявное преобразование для 0
?
Ответы
Ответ 1
От ECMA-334 (спецификация языка С#)
13.1.3. Неявные преобразования перечисления
Неявное преобразование перечислений допускает десятичное целое число-литерал 0 для преобразования в любой тип перечисления.
значение enum по умолчанию равно 0
, и во время компиляции известно, что это разрешено в инструкции switch. Для значения, отличного от 0
, во время компиляции не может быть определено, будет ли это значение существовать в перечислении или нет.
enum (ссылка С#)
Назначение дополнительных значений для новых версий перечислений или изменение значения членов перечисления в новой версии могут вызвать проблемы для зависимый исходный код. Часто бывает, что значения перечислены используется в операторах switch, и если добавлены дополнительные элементы к типу перечисления, проверка значений по умолчанию может вернуть true неожиданно.
Ответ 2
Я бы также добавил, что синтаксис с 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
.