Почему компилятор ведет себя по-другому с этим кодом? - PullRequest
8 голосов
/ 23 декабря 2009

В C # следующий метод не компилируется:

public bool IsItTrue()
{
}

Ошибки компилятора: IsItTrue (): не все пути кода возвращают значение, что имеет смысл. Но следующие компиляции без каких-либо проблем.

public bool IsItTrue()
{
    while (true)
    {
    }
}

Что выглядит неверно, так как нет возврата вообще. Почему это так? Любая помощь здесь ...,

Ответы [ 3 ]

13 голосов
/ 23 декабря 2009

Компилятор знает, что второй метод никогда не вернется.

Если какой-либо метод когда-либо возвращается в любых обстоятельствах, он должен вернуть bool.

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

Второй метод никогда не возвращается из-за бесконечного цикла while (true). Если он никогда не вернется, то не имеет значения, что (если вообще что-либо) будет никогда возвращено, поэтому компилятор позволит его скомпилировать.

Еще несколько примеров, которые компилятор распознает и разрешит:

public bool IsItTrue()
{
    throw new Exception("Always thrown!");
}

public bool HowAboutThisOne()
{
    if ((46 - 3) < (27 * 9))
    {
        throw new Exception("Always thrown!");
    }
}
3 голосов
/ 23 декабря 2009

Первое хорошо объясняется сообщением об ошибке компилятора.

Второй никогда не возвращает , поэтому никогда не возвращается ни одного значения.

Это не то же самое. В вашем первом примере метод может вернуться, не возвращая никакого значения вызывающей стороне -> Ошибка компилятора.

Второе никогда не вернется (компилятор достаточно умен для этого, он выясняет, что вы создали бесконечный цикл). Он никогда не войдет в состояние «Хорошо, я достиг конца метода и не знаю, что вернуть».

1 голос
/ 23 декабря 2009

Проблема остановки гласит, что вы обычно не можете определить, будет ли программа завершаться или работать вечно. Учитывая, что в этом потоке есть примеры, которые, кажется, нарушают этот принцип, я подозреваю, что компилятор C # выполняет анализ условий цикла, которые можно уменьшить до постоянной времени компиляции . Если константа имеет значение true, то мы знаем, что цикл никогда не прекратится.

Например, рассмотрим следующие две функции.

public bool NoError()
{
    while (true) { }
}

public bool Error()
{
    while (NoError()) { }
}

Как показано, первая функция не будет генерировать ошибку времени компиляции. Однако вторая будет, так как компилятор не может оценить результат вызова функции NoError(). Это также имеет место, если NoError() изменен так, чтобы всегда возвращать true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...