一般使用方法
 
 
yield 关键字向编译器指示它所在的方法是迭代器块
在迭代器块中,yield 关键字与 return 关键字结合使用,向枚举器对象提供值。 这是一个返回值,例如,在
foreach 语句的每一次循环中返回的值。 yield 关键字也可与 break 结合使用,表示迭代结束。
 
不允许不安全块。
 
方法、运算符或访问器的参数不能是 ref 或 out。
 
yield return 语句不能放在 try-catch 块中的任何位置。 该语句可放在后跟 finally 块的 try 块中。
 
yield break 语句可放在 try 块或 catch 块中,但不能放在 finally 块中。
yield 语句不能出现在匿名方法中
 
Yield的执行方法
调用函数
调用者请求item
下一个item返回
回到步骤2
 
 
yield不能单独放在try-catch块中,如果try中有yield那么,这个try块后面不许跟着finally块;也不能出现在匿名
方法中,所以,看起来yield似乎并不常用,但是也不是不用。我前面有一个关于迭代器的例子《C#中的迭代器基础
》中就用到了。可以参考一下那个例子,但是这里要再说的一点是我后来看到的,yield是跟return一起使用的,形
式为yield return xxx,一般来说单独的return在每个方法中只能存在一个。而yield则不同的是,可以出现连续多
个。
迭代器,是一个连续的集合,出现多个yield return其实就是将这多个的yield return元素按照出现的顺序存储在迭
代器的集合中而已
static IEnumerable<Int32> CountWithTimeLimit(DateTime limit)
{
    try
    {
        for (int i = 1; i <= 100; i++)
        {
            if (DateTime.Now >= limit)
            {
                yield break;
            }
            yield return i;
        }
    }
    finally
    {
        Console.WriteLine("停止迭代!"); Console.ReadKey();
    }
}
static void Main(string[] args)
{
    DateTime stop = DateTime.Now.AddSeconds(2);
    foreach (Int32 i in CountWithTimeLimit(stop))
    {
        Console.WriteLine("返回 {0}", i);
        Thread.Sleep(300);
    }
}
 
简单几行代码就能够完全实现IterationSampleIterator类所需要的功能。方法看起来很普通,除了使用了yield
return。这条语句告诉编译器这不是一个普通的方法,而是一个需要执行的迭代块(yield block),他返回一个
IEnumerator对象,你能够使用迭代块来执行迭代方法并返回一个IEnumerable需要实现的类型,IEnumerator或者对
应的泛型。如果实现的是非泛型版本的接口,迭代块返的yield type是Object类型,否则返回的是相应的泛型类型。
例如,如果方法实现IEnumerable<String>接口,那么yield返回的类型就是String类型。 在迭代块中除了yield
return外,不允许出现普通的return语句。块中的所有yield return 语句必须返回和块的最后返回类型兼容的类型
。举个例子,如果方法定义需要返回IEnumeratble<String>类型的话,不能yield return 1 。 需要强调的一点是,
对于迭代块,虽然我们写的方法看起来像是在顺序执行,实际上我们是让编译器来为我们创建了一个状态机。这就是
在C#1中我们书写的那部分代码---调用者每次调用只需要返回一个值,因此我们需要记住最后一次返回值时,在集合
中位置。 当编译器遇到迭代块是,它创建了一个实现了状态机的内部类。这个类记住了我们迭代器的准确当前位置
以及本地变量,包括参数。这个类有点类似与我们之前手写的那段代码,他将所有需要记录的状态保存为实例变量。
下面来看看,为了实现一个迭代器,这个状态机需要按顺序执行的操作:
 
它需要一些初始的状态
当MoveNext被调用时,他需要执行GetEnumerator方法中的代码来准备下一个待返回的数据。
当调用Current属性是,需要返回yielded的值。
需要知道什么时候迭代结束是,MoveNext会返回false
 
class Program
{
    static readonly String Padding = new String(' ', 30);
    static IEnumerable<Int32> CreateEnumerable()
    {
        Console.WriteLine("{0} CreateEnumerable()方法开始", Padding);
        for (int i = 0; i < 3; i++)
        {
            Console.WriteLine("{0}开始 yield {1}", i);
            yield return i;
            Console.WriteLine("{0}yield 结束", Padding);
        }
        Console.WriteLine("{0} Yielding最后一个值", Padding);
        yield return -1;
        Console.WriteLine("{0} CreateEnumerable()方法结束", Padding);
    }
 
    static void Main(string[] args)
    {
        IEnumerable<Int32> iterable = CreateEnumerable();
        IEnumerator<Int32> iterator = iterable.GetEnumerator();
        Console.WriteLine("开始迭代");
        while (true)
        {
            Console.WriteLine("调用MoveNext方法……");
            Boolean result = iterator.MoveNext();
            Console.WriteLine("MoveNext方法返回的{0}", result);
            if (!result)
            {
                break;
            }
            Console.WriteLine("获取当前值……");
            Console.WriteLine("获取到的当前值为{0}", iterator.Current);
        }
        Console.ReadKey();
    }
}
 
------------------------------------------------------------------------------------------
public class List
{
    //using System.Collections;
    public static IEnumerable Power(int number, int exponent)
    {
        int counter = 0;
        int result = 1;
        while (counter++ < exponent)
        {
            result = result * number;
            yield return result;
        }
    }
 
    static void Main()
    {
        // Display powers of 2 up to the exponent 8:
        foreach (int i in Power(2, 8))
        {
            Console.Write("{0} ", i);
        }
    }
}

yield 关键字和迭代器的更多相关文章

  1. C#使用yield关键字构建迭代器

    http://www.cnblogs.com/Huaran1chendu/p/4838536.html 以前,如果我们希望构建支持foreach枚举的自定义集合,只能实现IEnumerable接口(可 ...

  2. Python:容器、迭代对象、迭代器、生成器及yield关键字

            在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list, ...

  3. 使用yield关键字让自定义集合实现foreach遍历

    一般来说当我们创建自定义集合的时候为了让其能支持foreach遍历,就只能让其实现IEnumerable接口(可能还要实现IEnumerator接口) 但是我们也可以通过使用yield关键字构建的迭代 ...

  4. (转) Python Generators(生成器)——yield关键字

    http://blog.csdn.net/scelong/article/details/6969276 生成器是这样一个函数,它记住上一次返回时在函数体中的位置.对生成器函数的第二次(或第 n 次) ...

  5. 转载yield关键字理解

    实现IEnumerable接口及理解yield关键字   [摘要]本文介绍实现IEnumerable接口及理解yield关键字,并讨论IEnumerable接口如何使得foreach语句可以使用. 本 ...

  6. C# 基础小知识之yield 关键字 语法糖

    原文地址:http://www.cnblogs.com/santian/p/4389675.html 对于yield关键字我们首先看一下msdn的解释: 如果你在语句中使用 yield 关键字,则意味 ...

  7. C#2.0中使用yield关键字简化枚举器的实现

    我们知道要使用foreach语句从客户端代码中调用迭代器,必需实现IEnumerable接口来公开枚举器,IEnumerable是用来公开枚举器的,它并不实现枚举器,要实现枚举器必需实现IEnumer ...

  8. yield关键字

    1.yield语句有两种形式 (1)yield return <expression>;一次返回一个元素 运行yield return 语句时,会返回一个 值,并记录当前位置及保留该值.下 ...

  9. python yield 关键字

    最近看代码看到python里面的yield关键字,和我之前接触的语言好像都没有来着,我就查了查它的含义,大概理解如下: >>> def createGenerator(): ... ...

随机推荐

  1. 从零开始学习jQuery (七) jQuery动画-让页面动起来!

    一.摘要 本系列文章将带您进入jQuery的精彩世界, 其中有很多作者具体的使用经验和解决方案,  即使你会使用jQuery也能在阅读中发现些许秘籍. 开发人员一直痛疼做动画. 但是有了jQuery你 ...

  2. .Net 提交页面,js修改的Label值会丢掉

    <head id="Head1" runat="server"> <script src="../Jquery/jquery-1.1 ...

  3. Unity光照图UV显示

    美术的同学觉得 Unity 光照图烘焙的不够美丽,需要在 ps 里修一修,但是不知道每个物体对应的光照图在哪个区域,UV 是如何分布的,于是要求写一个工具显示,于是有了下面这个: 打开场景自动读取当前 ...

  4. Spark的几种运行模式

    1.local单机模式,结果xshell可见:./bin/spark-submit --class org.apache.spark.examples.SparkPi --master local[1 ...

  5. 解决Mac下Sequel Pro 1.1 连接 Homebrew安装Mysql5.7.8的问题 Sequel Pro 1.1 encountered an unexpected error

    解决Mac下Sequel Pro 1.1 连接 Homebrew安装Mysql5.7.8的问题 Sequel Pro encountered an unexpected error Sequel Pr ...

  6. codeforce 621C Wet Shark and Flowers

    题意:输入个n和质数p,n个区间,每个区间可以等概率的任选一个数,如果选的这个区间和它下个区间选的数的积是p的倍数的话(n的下个是1),就挣2000,问挣的期望 思路:整体的期望可以分成每对之间的期望 ...

  7. centos "cannot open display"的问题

    实用技巧:在Linux下设置xhost方法步骤 第一步:用root登陆linux,启动vnc服务: 第二步:根据vnc起来的端口,设置export DISPLAY=localhost:1(1表示vnc ...

  8. 2015 CCPC-C-The Battle of Chibi (UESTC 1217)(动态规划+树状数组)

    赛后当天学长就说了树状数组,结果在一个星期后赖床时才有了一点点思路…… 因为无法提交,不确定是否正确..嗯..有错希望指出,谢谢... 嗯..已经A了..提交地址http://acm.uestc.ed ...

  9. [四]SpringMvc学习-对servlet与json的支持与实现

    1.对servletAPI的支持 request.response.session作为参数自动注入 2.对Json的支持 2.1springmvc配置文件中添加支持对象与json的转换 <mvc ...

  10. oc学习之路----QQ聊天界面

    用到的技术:自定义cell,通知机制,代理模式 transform 1.自定义cell(通过代码自定义cell) ①首先新建一个类继承UITableViewCell ②重写initWithStyle: ...