代码之家  ›  专栏  ›  技术社区  ›  SLaks

巧妙使用.NET 2迭代器[关闭]

  •  14
  • SLaks  · 技术社区  · 15 年前

    C 2和VB.NET 8引入了一个新功能,叫做 iterators 它的目的是使返回可枚举和枚举器更容易。

    但是,迭代器实际上是 coroutines ,并且可以用于执行许多与对象集合无关的有用操作。

    您在实际代码中看到了迭代器的哪些非标准用法?

    5 回复  |  直到 12 年前
        1
  •  11
  •   SLaks    15 年前

    我用它们在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.");
       } 
    }
    

    您可以将迭代器存储在会话状态中,这样当用户返回到站点时,您只需将迭代器拉出,将迭代器移到下一页,并返回以进行呈现。复杂的站点交互是在一个地方编码的。

        2
  •  8
  •   Community CDub    7 年前

    开始工作:

    • Jeffrey Richter 使用迭代器编写了一个称为AsyncEnumerator的强大线程系统。它在msdn杂志上描述过,零件 one two .
    • 迭代器还可以用于在不阻塞UI线程的情况下等待方法内的UI交互,如我所描述的那样。 here .
    • 以类似的方式,我使用迭代器创建了一个基于IE的Web scraper,其中的scraping方法返回了 WebAction 在准备好时调用到枚举器的。(通常,当文档完成加载时)。
      如果有人感兴趣,我可以把它贴在这里。
        3
  •  1
  •   lmsasu    14 年前

    我使用它递归地迭代文件夹、子文件夹等中包含的文件。对于每个文件,我都必须执行特定的操作。对于其他人来说,带有“yield return”语句的递归函数很简单。

        4
  •  0
  •   ChaosPandion    15 年前

    在发现懒惰的yield操作符之前,我编写了这个函数。这将递归地构建一个大型迭代器并返回它。它并不完全有效,但我认为它很聪明。

    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 })
    
        5
  •  0
  •   Firo    12 年前

    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;
            }
        }
    }