Почему "Не все пути кода возвращают значение" с помощью оператора switch и перечисления?

У меня есть следующий код:

public int Method(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.Value1: return 1;
        case MyEnum.Value2: return 2;
        case MyEnum.Value3: return 3;
    }
}

public enum MyEnum
{
    Value1,
    Value2,
    Value3
}

И я получаю сообщение об ошибке: "Not all code paths return a value". Я не понимаю, как этот оператор switch никогда не мог перейти в один из указанных случаев.

Может ли enum быть null?

Ответ 1

Нечего сказать, что значение myEnum будет одним из этих значений.

Не перепутайте перечисления для ограничения набора значений. Это действительно просто именованный набор значений. Например, я мог бы вызвать ваш метод с помощью:

int x = Method((MyEnum) 127);

Что бы вы хотели этого сделать? Если вы хотите, чтобы это исключение, вы можете сделать это в случае по умолчанию:

switch (myEnum)
{
    case MyEnum.Value1: return 1;
    case MyEnum.Value2: return 2;
    case MyEnum.Value3: return 3;
    default: throw new ArgumentOutOfRangeException();
}

В качестве альтернативы вы можете использовать Enum.IsDefined upfront, если хотите выполнить некоторую другую работу перед оператором switch. У этого есть недостаток бокса... есть некоторые пути вокруг этого, но они, как правило, больше работают...

Пример:

public int Method(MyEnum myEnum)
{
    if (!IsDefined(typeof(MyEnum), myEnum)
    {
        throw new ArgumentOutOfRangeException(...);
    }
    // Adjust as necessary, e.g. by adding 1 or whatever
    return (int) myEnum; 
}

Это предполагает очевидную взаимосвязь между базовыми значениями в myEnum и значением, которое вы хотите вернуть.

Ответ 2

Перечисления не ограничиваются значениями, которые они представляют. Вы можете назначить это:

MyEnum v = (MyEnum)1000;

И не было бы никакой проблемы. Добавьте по умолчанию к вашему коммутатору, и вы будете обрабатывать все возможные ситуации.

Ответ 3

Если вы измените значения в своем перечислении (добавив четвертый), ваш код сломается. Вы должны добавить случай по умолчанию: к вашему оператору switch.

конечно, другим способом достичь этого было бы определение целочисленных значений в вашем перечислении...

public enum MyEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

а затем введите ваш enum как int в коде. Вместо int myInt = Method(myEnumValue); вы можете использовать int myInt = (int)myEnum

Ответ 4

MyEnum blah = 0;

Значение по умолчанию всегда равно 0 и неявно конвертируется, даже если у вас нет значения с 0.

Ответ 5

Он должен быть либо:

public int Method(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.Value1: return 1;
        case MyEnum.Value2: return 2;
        case MyEnum.Value3: return 3;
        default: return 0;
    }
}

или

public int Method(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.Value1: return 1;
        case MyEnum.Value2: return 2;
        case MyEnum.Value3: return 3;
    }

    return 0;
}