Подтвердить что ты не робот

Почему переключатель для перечисления принимает неявное преобразование в 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?

4b9b3361

Ответ 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.