Почему переключатель enum принимает неявное преобразование в 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
?
2 ответа
Из ECMA-334 (спецификация языка C#)
13.1.3 Неявные перечисления
Неявное преобразование перечисления позволяет преобразовать десятичный целочисленный литерал 0 в любой тип перечисления.
Значение по умолчанию для enum 0
и во время компиляции известно, поэтому это разрешено в операторе switch. Для значения, отличного от 0
во время компиляции нельзя определить, будет ли это значение в перечислении или нет.
Присвоение дополнительных значений новым версиям перечислений или изменение значений членов перечисления в новой версии может вызвать проблемы для зависимого исходного кода. Зачастую значения enum используются в выражениях switch, и если к типу enum добавлены дополнительные элементы, проверка значений по умолчанию может неожиданно вернуть true.
Я бы также добавил, что синтаксис с 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
,