Почему «Не все пути кода возвращают значение» с помощью оператора switch и enum? - PullRequest
26 голосов
/ 15 января 2010

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

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?

Ответы [ 5 ]

37 голосов
/ 15 января 2010

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

5 голосов
/ 15 января 2010

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

MyEnum v = (MyEnum)1000;

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

0 голосов
/ 15 января 2010
MyEnum blah = 0;

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

0 голосов
/ 15 января 2010

Это должно быть:

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;
}
0 голосов
/ 15 января 2010

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

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

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

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

...