zoukankan      html  css  js  c++  java
  • 迭代器 与 foreach 的区别

    迭代器的常见运用--Eg:有一组数据 需要对每个符合条件的数据 进行记录

           static void Main()
            {
                int[] s = new int[] { 1, 2, 8 };
                foreach (int term in GetSingleDigitNumbers(s))
                {
                    Console.WriteLine(term);
                }
    
                Console.ReadKey();
            }
           
            public static IEnumerable<int> GetSingleDigitNumbers(int[] s)
            {
                foreach (var item in s)
                {
                    if (item%2==0)
                    {
                        yield return item;
                    }              
                }
            }
    

    结果:

    这里看来 好像直接foreach就能实现
    起先我并不明白 两者使用起来到底有什么区别 直到我看到以下实例

    IEnumerable<int> Fibonacci(int count)
    {
      int prev = 1;
      int curr = 1;
      for (int i = 0; i < count; i++)
      {
        yield return prev; //把程序控制权交回调用者 同时保留方法本地状态,等到调用者拿到返回的值后 该方法继续往后执行
        int temp = prev + curr;
        prev = curr;
        curr = temp;
      }
    }
    
    void Main()
    {
      foreach (int term in Fibonacci(10))
      {
        Console.WriteLine(term);
      }
    }
    

    对应输出结果

    可发现调用Fibonacci 每次返回结果后 依旧继续往后执行 直至此次for结束后 继续进行Fibonacci的for循环 直至循环结束 这样就将符合条件的一组值返回给了调用者

    而foreach循环 return后 后续是不会执行的 且 foreach依赖于 .NET Core 库中定义的 2 个泛型接口,才能生成循环访问集合所需的代码:IEnumerable 和 IEnumerator

    此外iterators是使用时 才真正调用执行的 Eg:

      static void Main()
            {
                int[] s = new int[] { 1, 2, 8 };
                var p = GetSingleDigitNumbers(s);//此时直接返回符合条件的 IEnumerable<int>{2,8};不会真正的执行方法内操作【 Console.WriteLine("The method was called.");】
    
                //如果p不被调用 则永远不会执行GetSingleDigitNumbers方法内额外的操作【 Console.WriteLine("The method was called.");】
                foreach (var item in p)//直至调用时才执行 方法内操作【 Console.WriteLine("The method was called.");】
                {
                    Console.WriteLine(item);
                }
              
                Console.ReadKey();
            }
           
            public static IEnumerable<int> GetSingleDigitNumbers(int[] s)
            {
                foreach (var item in s)
                {
                    if (item%2==0)
                    {
                        yield return item;
                       Console.WriteLine("The method was called.");
                    }              
                }
            }
    

    结果:

    总结:

    • foreach:
      * 通过 return 语句立即把程序的控制权交回给调用者,同时也会把方法内的本地资源释放掉
      * 依赖于 .NET Core 库中定义的 2 个泛型接口,才能生成循环访问集合所需的代码:IEnumerable 和 IEnumerator
    • iterator:
      * 使用yeild return 可依次返回多个值给调用者的期间仍保留方法内本地资源,等所有值都返回结束时,再释放掉方法内资源,这些返回的值形成一组序列被调用者使用
      * 同一方法中不能同时使用 return 语句和 yield return 语句
      * 本身仅返回一组有效值 方法内额外操作 仅在结果被调用时执行
  • 相关阅读:
    HDU
    纯C++去雾算法
    拓扑排序
    SG 函数初步 HDU 1536 &amp;&amp; HDU 1944
    <html>
    XML制作RSS源
    ACM退役前2个月总结
    javascript 的 jasmine 的測试语句
    Vue.js父与子组件之间传参
    $.contents().find设置的data在iframe子页面无法获取值
  • 原文地址:https://www.cnblogs.com/Alicia-meng/p/13495216.html
Copyright © 2011-2022 走看看