一般使用方法
 
 
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. ASP.NET操作Word的IIS权限配置

    ASP.NET账号在默认情况下是没有权限操作Microsoft Office对象的,如果不进行权限的配置,代码会抛出类似以下的异常: 检索 COM 类工厂中 CLSID 为 {00024500-000 ...

  2. [原创][下载]Senparc.Weixin.MP-微信公众平台SDK(C#) - 已支持微信6.x API

    因为正在计划做一个微信机器人,需要用ASP.NET,找了一下只有PHP的SDK,没有C#的,于是动手写了一个,已经全面支持微信6.x所有接口,包括多客服.卡券.微信支付等. 微信公众平台地址:http ...

  3. HDU 3427

    DP: According to the meaning of problems,if we check n to m, assume x and y are both solvable,then w ...

  4. Introduction to SignalR -摘自网络

    What is SignalR? ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of ...

  5. ios中view的生命周期

  6. storm的特性

    storm的特性 Storm 是一个开源的分布式实时计算系统,可以简单.可靠地处理大量的数据流. Storm支持水平扩展,具有高容错性,保证每个消息都会得到处理,而且处理速度很快(在一个小集群中,每个 ...

  7. Ⅸ.spring的点点滴滴--IObjectFactory与IFactoryObject的杂谈

    承接上文 ObjectFactory与IFactoryObject的杂谈 .net篇(环境为vs2012+Spring.Core.dll v1.31) public class parent { pu ...

  8. 按需讲解之Supervisor

    Supervisor是一个进程监控程序. 满足的需求是:我现在有一个进程需要每时每刻不断的跑,但是这个进程又有可能由于各种原因有可能中断.当进程中断的时候我希望能自动重新启动它,此时,我就需要使用到了 ...

  9. SweetAlert 使用

    $(".delete").click(function(){ var work_name = $(this).data('name'); var item_id = $(this) ...

  10. 自己动手Jquery插件

    最近Web应用程序中越来越多地用到了JQuery等Web前端技术.这些技术框架有效地改善了用户的操作体验,同时也提高了开发人员构造丰富客户 端UI的效率.JQuery本身提供了丰富的操作,但是,有时候 ...