Некоторое понимание справки “урожай”

36
задан Boris Callens 13 April 2017 в 09:55
поделиться

6 ответов

Метод с помощью возврат урожая должен быть объявлен как возврат одного из следующих двух интерфейсов:

IEnumerable<SomethingAppropriate>
IEnumerator<SomethingApropriate>

(спасибо Jon и Marc для указания на IEnumerator)

Пример:

public IEnumerable<AClass> YourMethod()
{
    foreach (XElement header in headersXml.Root.Elements())
    {
        yield return (ParseHeader(header));                
    }
}

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

, Таким образом, существует различие, и необходимо объявить метод правильно.

Для получения дополнительной информации читавший ответ Jon здесь , который содержит некоторые очень полезные ссылки.

32
ответ дан Community 27 November 2019 в 05:52
поделиться

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

у меня есть несколько ресурсов на этом:

15
ответ дан Jon Skeet 27 November 2019 в 05:52
поделиться

"урожай" создает блок итератора - компилятор генерировал класс, который может реализовать или IEnumerable[<T>] или IEnumerator[<T>]. У Jon Skeet есть очень хорошее (и свободный) обсуждение этого в главе 6 C# подробно .

, Но в основном - для использования "урожая" метод должен возвратиться IEnumerable[<T>] или IEnumerator[<T>]. В этом случае:

public IEnumerable<AClass> SomeMethod() {
    // ...
    foreach (XElement header in headersXml.Root.Elements()){
        yield return (ParseHeader(header));                
    }
}
8
ответ дан Marc Gravell 27 November 2019 в 05:52
поделиться

Список реализует Ienumerable.

Вот пример, который мог бы пролить некоторый свет на то, что Вы пытаетесь изучить. Я записал этому приблизительно 6 месяцев

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace YieldReturnTest
{
    public class PrimeFinder
    {
        private Boolean isPrime(int integer)
        {
            if (0 == integer)
                return false;

            if (3 > integer)
                return true;

            for (int i = 2; i < integer; i++)
            {
                if (0 == integer % i)
                    return false;
            }
            return true;
        }

        public IEnumerable<int> FindPrimes()
        {
            int i;

            for (i = 1; i < 2147483647; i++)
            {
                if (isPrime(i))
                {
                    yield return i;
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            PrimeFinder primes = new PrimeFinder();

            foreach (int i in primes.FindPrimes())
            {
                Console.WriteLine(i);
                Console.ReadLine();
            }

            Console.ReadLine();
            Console.ReadLine();
        }
    }
}
3
ответ дан Ian P 27 November 2019 в 05:52
поделиться

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

3
ответ дан Simon Steele 27 November 2019 в 05:52
поделиться

Что делает метод, который Вы используете, это в похоже? Я не думаю, что это может использоваться в просто цикле отдельно.

, Например...

public IEnumerable<string> GetValues() {
    foreach(string value in someArray) {
        if (value.StartsWith("A")) { yield return value; }
    }
}
0
ответ дан Hugoware 27 November 2019 в 05:52
поделиться
Другие вопросы по тегам:

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