Умное использование.Net 2 Iterators

C# 2 и VB.Net 8 представили новую функцию, называемую итераторы, которые были разработаны для облегчения возврата перечислимых и перечислителей.

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

Какие нестандартные применения итераторов вы видели в реальном коде?

5 ответов

Решение

Я использовал их, чтобы написать систему в ASP.NET для создания серии взаимодействий связанных страниц. Если вы представляете разговор пользователя с веб-сайтом в виде последовательности запросов и ответов, вы можете смоделировать взаимодействие как IEnumerable, Концептуально, вот так;

IEnumerable<PageResponse> SignupProcess(FormValues form)
{
   // signup starts with a welcome page, asking
   // the user to accept the license.
   yield return new WelcomePageResponse();

   // if they don't accept the terms, direct 
   // them to a 'thanks anyway' screen
   if (!form["userAcceptsTerms"])
   {
      yield return new ThanksForYourTimePageResponse();
      yield break;
   }

   // On the second page, we gather their email;
   yield new EmailCapturePage("");
   while(!IsValid(form["address"]))
   {
     // loop until we get a valid address.
     yield return new EmailCapturePage("The email address is incorrect. Please fix.");
   } 
}

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

Для начала:

  • Джеффри Рихтер написал мощную систему потоков AsyncEnumerator с использованием итераторов. Это описано в журнале MSDN, части первая и вторая.
  • Итераторы также можно использовать для ожидания взаимодействия пользовательского интерфейса в методе, не блокируя поток пользовательского интерфейса, как я описал здесь.
  • В том же духе я использовал итераторы для создания веб-скребка на основе IE с методами очистки, которые возвращают IEnumerators WebActions, которые перезванивают в перечислитель, когда готовы. (Как правило, когда документ заканчивается загрузкой).
    Если людям интересно, я могу опубликовать это здесь.

Я использовал его для рекурсивного перебора файлов, содержащихся в папке, ее подпапках и так далее. Для каждого файла мне нужно было выполнить определенное действие. Рекурсивная функция с операторами "yield return" была простой для понимания всех остальных.

Я написал эту функцию до того, как узнал об операторе ленивого выхода. Это рекурсивно создает массивный итератор и возвращает его. Это не совсем эффективно, но я думаю, что это умно.

static member generatePrimeNumbers max =    
    let rec generate number numberSequence =
        if number * number > max then numberSequence else
        let filteredNumbers = numberSequence |> Seq.filter (fun v -> v = number || v % number <> 0L)
        let newNumberSequence = seq { for i in filteredNumbers -> i }
        let newNumber = newNumberSequence |> Seq.find (fun x -> x > number)
        generate newNumber newNumberSequence                
    generate 2L (seq { for i in 2L..max -> i })

Rhino.ETL интенсивно использует его для объединения преобразований в последовательности ввода

например 3 операции, которые можно комбинировать, использовать повторно

public IEnumerable<Row> Execute(IEnumerable<Row> rows)
{
    foreach(var line in File.EnumerateLines())
    {
        var row = new Row();
        row["key"] = int.Parse(line.Substring(1));
        yield return row;
    }
}

public IEnumerable<Row> Execute(IEnumerable<Row> rows)
{
    foreach(var row in rows)
    {
        var value = (int)row["key"];
        row["key"] = value + 2;
        yield return row;
    }
}

public IEnumerable<Row> Execute(IEnumerable<Row> rows)
{
    using (var file = new Streamwriter(filename))
    {
        foreach(var row in rows)
        {
            file.WriteLine(row["key"]);
            yield return row;
        }
    }
}
Другие вопросы по тегам