一般使用方法
 
 
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. hadoop学习笔记——基础知识及安装

    1.核心 HDFS  分布式文件系统    主从结构,一个namenoe和多个datanode, 分别对应独立的物理机器 1) NameNode是主服务器,管理文件系统的命名空间和客户端对文件的访问操 ...

  2. Paxos算法(转)

    Paxos算法的难理解与算法的知名度一样令人敬仰,从我个人的经历而言,难理解的原因并不是该算法高深到大家智商不够,而在于Lamport在表达该算法时过于晦涩且缺乏一个完整的应用场景.如果大师能换种思路 ...

  3. 【转】Django+Mysql安装配置详解(Linux)

    参考:http://dmyz.org/archives/110 报错TemplateDoesNotExist at 解决: 新建mysite/articles/article.html文件: 文件内容 ...

  4. LCD驱动(FrameBuffer)实例开发讲解

    一.开发环境 主  机:VMWare--Fedora 9 开发板:Mini2440--64MB Nand, Kernel:2.6.30.4 编译器:arm-linux-gcc-4.3.2 二.背景知识 ...

  5. leetcode—Populating Next Right Pointers in Each Node

    1.题目描述 Given a binary tree   struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLink ...

  6. strust1.x中formbean的原理及作用

    from:     http://blog.csdn.net/tuiroger/article/details/3947896 今天张老师讲了一些比较重要的strust标签,<html:link ...

  7. 引入less报错解决方法以及浏览器设计不同的地方

    XMLHttpRequest cannot load file:///C:/Users/PAXST/Desktop/805/first.less. Cross origin requests are ...

  8. Java 动态生成 复杂 .doc文件

    阅读目录 1.word 里面调整好排版,包括你想生成的动态部分,还有一些不用生成的规则性的文字 2. 将 word 文档保存为 xml 3.用 Firstobject free XML edito 打 ...

  9. MVC模式网站编写经验总结

    单个网站使用MVC架构模式经验总结,包含具体网站包分类.包内类的编写.注意事项等方面.本人认为,按照如下包分类及编写方法,已经满足一个简单普通网站(主要针对java)的编写需求. MVC主要层级 数据 ...

  10. 算法基础:最大递减数问题(Golang实现)

    给出一个非负整数,找到这个非负整数中包括的最大递减数.一个数字的递减数是指相邻的数位从大到小排列的数字. 如: 95345323,递减数有:953,95,53,53,532,32, 那么最大的递减数为 ...