Почему переключатель 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 (C# Reference)

Присвоение дополнительных значений новым версиям перечислений или изменение значений членов перечисления в новой версии может вызвать проблемы для зависимого исходного кода. Зачастую значения 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,

Другие вопросы по тегам