Не все пути кода возвращают значение - но они - PullRequest
4 голосов
/ 30 марта 2012

Не удается скомпилировать следующий фрагмент кода, что приводит к not code paths return a value.Оба типа Test1StandardChargeCalculator и Test2StandardChargeCalculator являются производными от типа возвращаемого значения.

Я знаю, как это исправить , но у меня такой вопрос, почему я должен это делать?bool является типом значения - следовательно, может представлять только true или false , оба из которых учитываются в этом фрагменте.Так почему неудачная компиляция?

internal StandardChargeCalculator Create()
{
      bool value = true;

      switch (value)
      {
          case true:
              return new Test1StandardChargeCalculator();
          case false:
              return new Test2StandardChargeCalculator();
      }
} //not all code paths return a value

Ответы [ 5 ]

15 голосов
/ 30 марта 2012

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

Ошибка возникает из-за того, что у вас нет случая по умолчанию .

Не используйте switch для логического теста - используйте оператор if:

  bool value = true;

  if(value)
  {
      return new Test1StandardChargeCalculator();
  }

  return new Test2StandardChargeCalculator();
4 голосов
/ 30 марта 2012

В Отсутствие доказательств не является доказательством отсутствия Эрик Липперт пишет об ограничениях «доказательства» того, что переменная не назначена, и более слабой цели компилятора в этом отношении:

что мы не заинтересованы в доказательстве того, что x не назначен.Мы заинтересованы в том, чтобы доказать, что х назначен!Если мы можем доказать это наверняка, то x «определенно назначен».Если мы не можем доказать это наверняка, тогда x «определенно не назначен».

Что не объясняет этот пример напрямую, но обратите внимание, что это та же проблема, что и:

int x;

if (a < 10) 
   x = 0;
else if (a >= 10)
   x = 1;

y = x; // x is 'unassigned'

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

4 голосов
/ 30 марта 2012

Почему, по вашему мнению, компилятор должен использовать логическое значение для особого случая и обнаруживать, что все возможные значения имеют оператор case?

Если бы вы писали компилятор, вы бы вложили усилия в разработку и увеличили бы риск ошибок, внедрив это?

0 голосов
/ 30 марта 2012

Насколько я понимаю, это не соответствует определению переключателя, которое гласит:

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

Вы правы: ошибки компилятора не должно быть. Таким образом, это может быть случай, когда нет ответа. Вам придется с этим жить.

    switch (answer)
    {
    ...
    default:
    return "It is as it is"
    }
0 голосов
/ 30 марта 2012

Возможно, лучшим решением будет

internal StandardChargeCalculator Create()
{
  StandardChargeCalculator result = null;
  bool value = true;

  switch (value)
  {
    case true:
      result = new Test1StandardChargeCalculator();
      break;
    case false:
      result = new Test2StandardChargeCalculator();
      break;
  }
  return result;
}
...