Возвращаемое значение и "не все пути кода возвращают значение" - PullRequest
0 голосов
/ 16 декабря 2018

Почему следующий код:

private static IEnumerable<int> TestYield(bool check)
{
    if (check)
    {
        return 1;
    }
    else
    {
        Console.WriteLine("In the else");
    }
}

выдает ошибку с «возвращаемое значение не для всех путей кода».Однако следующий код не выдает такую ​​же ошибку:

private static IEnumerable<int> TestYield(bool check)
{
    if (check)
    {
        yield return 1;
    }
    else
    {
        Console.WriteLine("In the else");
    }
}

Единственная разница - доходность.Какая доходность отличается, что не вызывает одну и ту же ошибку?

Ответы [ 3 ]

0 голосов
/ 16 декабря 2018

В вашем первом коде вы возвращаете только 1, которое является единственным целочисленным значением, но тип возвращаемого значения метода -

IEnumerable<int>

согласно Microsoft;Они четко сказали, что вы должны использовать

 yield return statement to return each element one at a time. 

. Вы используете метод итератора, используя оператор foreach или LINQ запрос.В общем, если вы не хотите выполнять итерацию, то нет необходимости использовать yield и IEnumerable, но если вы действительно хотите выполнять итерацию по своим данным или файлу, вам следует использовать yield .

Пожалуйста, прочитайте Выход по MS для получения дополнительной информации.

0 голосов
/ 16 декабря 2018

Когда вы используете просто return, потому что ваш оператор else ничего не возвращает, он выдает ошибку, о которой вы упомянули, и, так как вы возвращаете тип int, он также выдает ошибку «не удается преобразовать тип выражения int в тип возврата IEnumerable».

Когда вы используете возвращение дохода, под обложками ключевое слово yield создает конечный автомат для хранения информации о состоянии.В соответствии с MSDN : «Когда в методе итератора достигается оператор return yield, выражение возвращается, и текущее местоположение в коде сохраняется. Выполнение перезапускается из этого местоположения при следующем вызове функции итератора.Позвонил. "

Теперь на ваш вопрос" что происходит в другой стороне ", я посмотрел сгенерированный код IL с ILSpy.Я создал класс с именем YTest и добавил метод, который возвращает с yield.Вот сгенерированный код:

internal class YTest
{
    [IteratorStateMachine(typeof(YTest.<TestYield>d__0))]
    public static IEnumerable<int> TestYield(bool check)
    {
        int num;
        while (num == 0)
        {
            if (!check)
            {
                Console.WriteLine("In the else");
                IL_52:
                yield break;
            }
            yield return 1;
        }
        if (num != 1)
        {
            yield break;
        }
        goto IL_52;
    }
}

Компилятор добавляет скрытую инструкцию yield break.

При работе с ключевым словом yield необходимо учитывать эти моменты (помимо msdn, кавычкис https://www.infoworld.com/article/3122592/application-development/my-two-cents-on-the-yield-keyword-in-c.html

):

  • Вы не можете иметь оператор yield return в блоке try-catch, хотя вы можете иметь его внутри try-finallyblock

  • Вы не можете иметь оператор break в блоке finally

  • Тип возвращаемого значения метода, в котором был использован yield, должен бытьIEnumerable, IEnumerable, IEnumerator или IEnumerator

  • В вашем методе нельзя использовать параметр ref или out, в котором был использован yield

  • Youнельзя использовать операторы yield return или «yield break» внутри анонимных методов

  • Нельзя использовать операторы yield return или «yield break» внутри «небезопасных» методов,т. е. методы, помеченные
    «небезопасным» kслово, обозначающее небезопасный контекст

0 голосов
/ 16 декабря 2018

Любое тело метода, содержащее оператор yield break или yield return, является блоком итератора .Внутри блока итератора для выполнения допустимо достичь закрывающей скобки метода, поскольку это просто эквивалентно наличию yield break - это конец последовательности.

В обычном методе с неvoid тип возвращаемого значения - ошибка в доступной закрывающей скобке оператора.(Кроме того, return 1; не является допустимым оператором в обычном методе с типом возврата IEnumerable<int>.)

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