Вопрос по c# – Компилятор .NET и «Не все пути кода возвращают значение»

2

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

<code>bool Test(bool param) {
    bool test = true;
    if (param)
        test = false;
    else
        test = false;
    if (!test)
        return false;
}
</code>

Ошибка CS0161: не все пути кода возвращают значение!

Код можно реорганизовать, но компилятор этого не предлагает. Все же все пути возврата покрыты - так почему компилятор жалуется, что это не так?

Редактировать: я думаю, что вывод здесь таков:

<code>(error CS0161) + (all code paths obviously return a value) => refactor code.  
</code>

Как только вы привыкнете к этому переводу, я думаю, все в порядке.

Эта функция в ее текущем состоянии бесполезна, так какif (!test) return false должен быть ТОЛЬКОreturn false, Я не вижу никакого значения, пытаясь понять, почему бесполезная функция выдает предупреждение / ошибку. Erik Philips
Я предполагаю, что разработчики не чувствовали необходимости обслуживать такой код. David Heffernan
Но это все еще может быть тривиально рефакторинг для устранения избыточности. И тогда я подозреваю, что это больше не вызовет ошибку. Думайте об этом как о тонком побуждении следоватьgood design practice. Cody Gray♦
Есть ли настоящий фрагментuseful код, для которого вы видите эту ошибку компилятора? Cody Gray♦
В ответ на ваше изменение: ответ dtb правильный. В статье Эрика Липперта не только говорится, что «анализатор достижимости не очень умен». но также и то, что «этот недостаток языкового дизайна глуп, но, честно говоря, у нас есть более высокие приоритеты, чем исправление этого глупого случая». Решение здесь не в том, чтобы исправить компилятор; скорее, это удалитьif (!power_args_ok) линия. Кроме того, вы можете броситьnew Exception("power_args_ok is unexpectedly true") чтобы защитить себя от ошибок в этом методе. phoog

Ваш Ответ

5   ответов
3

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

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

10

Блог Эрика Липперта:

The reachability analyzer is not very smart. It does not realize that there are only two possible control flows and that we've covered all of them with returns.

(The blog post is on switch statements, but I guess the reachability analyzer isn't much smarter for if statements.)

0

чтобы вдаваться в подробности, позвольте мне прямо ответить на ваш вопрос.

Return type of function is specified as Bool hence the function must return True or false Param has been defined as input parameter hence its value can not be determined at compile time value of test variable is dependent on param and as per step-2, param value can not be determined at compile time and hence value of test can not be determined at compile time As value of test is not known as com,pile time(as per step-3) hence it start looking for a else / default root for if (!test) and hence it throws error.

Спасибо

1

Problem: Code doesn't return any value.

Question: Где в коде возвращается значение?

Answer: Просто на последней строчке.

Conclusion: Так что эта строка кода (последняя строка) всегда должна возвращать значение.

Question: Всегда ли последняя строка возвращает значение?

Answer: Нет, он возвращает значение только еслиtest являетсяfalse в то время как это было установлено вtrue на первой линии.

Conclusion: Как говорит компилятор, эта функция никогда не возвращает значение, пока она должна возвращатьbool.

11

10.6.10 "Method body":

When the return type of a method is not void, each return statement in that method’s body must specify an expression that is implicitly convertible to the return type. The endpoint of the method body of a value-returning method must not be reachable. In other words, in a value-returning method, control is not permitted to flow off the end of the method body.

Определениеreachability здесь (выделение добавлено):

8.1 "End points and reachability":

If a statement can possibly be reached by execution, the statement is said to be reachable. Conversely, if there is no possibility that a statement will be executed, the statement is said to be unreachable.

...

To determine whether a particular statement or end point is reachable, the compiler performs flow analysis according to the reachability rules defined for each statement. The flow analysis takes into account the values of constant expressions (§7.19) that control the behavior of statements, but the possible values of non-constant expressions are not considered.

поскольку!test не является постоянным выражением (даже если оно всегда будетtrue), компилятор обязан не учитывать это при анализе потока. Одна из причин (возможно, единственная причина) этого ограничения заключается в том, что выполнение такого анализа потока невозможно в общем случае.

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Ricibob

Похожие вопросы