C# yield return 和 yield break

原创 2016年08月29日 16:35:20

    1. 在语句中使用 yield 关键字,表示在该关键字所在的方法、运算符或 get 访问器是迭代器。 通过使用 yield 定义迭代器,可在实现自定义集合类型的 IEnumerable 和 IEnumerator 模式时无需其他显式类

    2.yield return 用于返回IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>,一次返回一个元素。yield break用于终止循环遍历。

    3. 通过 foreach 语句或 LINQ 查询来使用迭代器方法。 foreach 循环的每次迭代都会调用迭代器方法。 迭代器方法运行到 yield return 语句时,会返回一个 expression,并保留当前在代码中的位置。 当下次调用迭代器函数时执行从该位置重新启动。
   4. 可以使用 yield break 语句来终止迭代。

   5.迭代器的声明必须满足以下要求:

    返回类型必须为 IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>。

    该声明不能有任何 ref 或out参数。

    6.不能在具有以下特点的方法中包含 yield return 或 yield break 语句:

    匿名方法。
    包含不安全的块的方法

    7.异常处理:

     不能将 yield return 语句置于 try-catch 块中。 可将 yield return 语句置于 try-finally 语句的 try 块中。

    yield break 语句可以位于 try 块或 catch 块,但不能位于 finally 块。

    如果 foreach 主体(在迭代器方法之外)引发异常,则将执行迭代器方法中的 finally 块。

    8.举例:

    

      public static IEnumerable<int> Power1(int number, int exponent)
        {
            List<int> list = new List<int>();
            int result = 1;
            for (int i = 0; i < exponent; i++)
            {
                result = result * number;
                list.Add(result);
            }
            return list;
        }

       public static IEnumerable<int> Power2(int number, int exponent)
        {
            int result = 1;
            for (int i = 0; i < exponent; i++)
            {
                result = result * number;
                yield return result;
            }
        }

 static void Main(string[] args)
        {
            //IEnumerable<int> list = Power1(2, 8);
<pre name="code" class="csharp">            IEnumerable<int> list = Power2(2, 8);
 foreach (int l in list) { Console.WriteLine("{0}",l); } }


虽然2种方法的输出结果是一样的,但运作过程迥然不同。第一种方法,是把结果集全部加载到内存中再遍历;第二种方法,客户端每调用一次,yield return就返回一个值给客户端,是"按需供给"。

当调用power2时,并不立即执行该方法,在foreach循环时,将为list调用MonveNext方法,此时才执行Power2方法,知道下一个yield return语句,yield return语句返回的表达式不仅决定了循环体使用的l变量值,还决定了元素的Current属性值(它是IEnumerable<int>类型)。

使用yield return为什么能保证每次循环遍历的时候从前一次停止的地方开始执行呢?--因为,编译器会生成一个状态机来维护迭代器的状态。

9.总结:当希望获取一个IEnumerable<T>类型的集合,而不想把数据一次性加载到内存,就可以考虑使用yield return实现"按需供给"。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C# 中 yield return 和 yield break 关键字的用法

yield 关键字向编译器指示它所在的方法是迭代器块。 编译器生成一个类来实现迭代器块中表示的行为。 在迭代器块中,yield 关键字与 return 关键字结合使用,向枚举器对象提供值。 这...

C#笔记 协程coroutines yield return

coroutines在unity里用处多多,用的好可以大量简化代码。 例如: 让loading场景绘制进度条不阻塞,这里异步加载关卡的函数还是必须的。 简化编写不同阶段不同行为的GameObje...
  • fjl2007
  • fjl2007
  • 2015年07月13日 11:39
  • 2620

C# yield return用法分析

原文:http://www.jb51.net/article/54810.htm 本文实例讲述了C#中yield return用法,并且对比了使用yield return与不使用yield ...
  • for_cxc
  • for_cxc
  • 2016年03月09日 14:09
  • 175

C# 2.0 新特性之迭代器, Yield Return

本文摘自:http://www.cnblogs.com/montaque/archive/2005/04/21/142844.htmlC# 2.0 可能讨论比较多的是泛型, 其次可能就是迭代器,匿名方...
  • VS_URL
  • VS_URL
  • 2012年07月23日 15:15
  • 1294

C#中yield return用法分析

本文实例讲述了C#中yield return用法,并且对比了使用yield return与不使用yield return的情况,以便读者更好的进行理解。具体如下: yield关键字用于遍历循环中,y...
  • cbbbc
  • cbbbc
  • 2015年12月09日 10:36
  • 1871

Unity3D: StartCoroutine 和 yield return 深入研究

StartCoroutine和yield return表面意思很好理解,StartCoroutine就是开启一个协程,yield return 是迭代器块返回调用迭代的地方。 是吧?不知道你什么感觉...

yield return的使用

对于一个C# beginner,yield return / StartCoroutine() 总是会理解的比较模糊,本人在这里不想(也不会)去说具体的内涵,仅从实验的角度来给出例子,希望对以后使用有...

IEnumerator/ IEnumerable/ yield return/ StartCoroutine 详解

IEnumerator/ IEnumerablepublic interface IEnumerable { IEnumerator GetEnumerator(); } ...

关于协程中yield return的一些使用

1.协程与线程 Unity中的特殊在于所有的脚本和代码都是在一个主线程里运行的,协程也不例外。协程与线程的相似点只在于,协程看起来也可以与其他函数并行执行。 但本质上来说,线程 是通过可以开启多个...

使用yield return返回迭代器的方法的“延迟执行”的内幕

最近看书时偶然发现的,使用yield return的方法有延迟执行的特性。 先看代码吧: static void Main(string[] args) { ...
  • ghw1419
  • ghw1419
  • 2013年02月21日 16:18
  • 1081
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# yield return 和 yield break
举报原因:
原因补充:

(最多只允许输入30个字)