C#中的foreach和yield

来源:互联网 发布:阿里云ecs windows教程 编辑:程序博客网 时间:2024/05/16 07:21

 

1. foreach

C#编译器会把foreach语句转换为IEnumerable接口的方法和属性。

foreach (Person p in persons) {     Console.WriteLine(p); }

foreach语句会解析为下面的代码段。

调用GetEnumerator()方法,获得数组的一个枚举

在while循环中,只要MoveNext()返回true,就一直循环下去

用Current属性访问数组中的元素


IEnumerator enumerator = persons. GetEnumerator(); while (enumerator.MoveNext()) {    Person p = (Person) enumerator.Current;    Console.WriteLine(p);}

2. yield语句

yield语句的两种形式:

yield return <expression>;yield break;

使用一个yield return语句返回集合的一个元素

包含yield语句的方法或属性是迭代器。迭代器必须满足以下要求

a. 返回类型必须是IEnumerable、IEnumerable<T>、IEnumerator或 IEnumerator<T>。

b. 它不能有任何ref或out参数

yield return语句不能位于try-catch快。yield return语句可以位于try-finally的try块


try              {                  // ERROR: Cannot yield a value in the boday of a try block with a catch clause                 yield return "test";              }             catch             { }               try             {                 //                  yield return "test again";             }             finally             { }              try             { }             finally             {                  // ERROR: Cannot yield in the body of a finally clause                yield return "";              }

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

下面的例子是用yield return语句实现一个简单集合的代码,以及用foreach语句迭代集合


using System;using System.Collections.Generic;namespace ConsoleApplication6{    class Program    {        static void Main(string[] args)        {            HelloCollection helloCollection = new HelloCollection();            foreach (string s in helloCollection)            {                Console.WriteLine(s);                Console.ReadLine();            }        }    }    public class HelloCollection    {                public IEnumerator<String> GetEnumerator()        {            // yield return语句返回集合的一个元素,并移动到下一个元素上;yield break可以停止迭代            yield return "Hello";            yield return "World";        }    }}

使用yield return语句实现以不同方式迭代集合的类:


using System;using System.Collections.Generic;namespace ConsoleApplication8{    class Program    {        static void Main(string[] args)        {            MusicTitles titles = new MusicTitles();            foreach (string title in titles)            {                Console.WriteLine(title);            }            Console.WriteLine();            foreach (string title in titles.Reverse())            {                Console.WriteLine(title);            }            Console.WriteLine();            foreach (string title in titles.Subset(2, 2))            {                Console.WriteLine(title);                Console.ReadLine();            }        }    }    public class MusicTitles    {        string[] names = { "a", "b", "c", "d" };        public IEnumerator<string> GetEnumerator()        {            for (int i = 0; i < 4; i++)            {                yield return names[i];            }        }        public IEnumerable<string> Reverse()        {            for (int i = 3; i >= 0; i--)            {                yield return names[i];            }        }        public IEnumerable<string> Subset(int index, int length)        {            for (int i = index; i < index + length; i++)            {                yield return names[i];            }        }    }}

 

 

 

以上动图由“图斗罗”提供

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一个多月的宝宝老是哭闹怎么办 宝宝头老往后仰怎么办 8个月宝宝不会爬怎么办 孩子个头长得慢怎么办 宝宝个头长得慢怎么办 婴儿个头长得慢怎么办 11个月宝宝认生怎么办 3个月宝宝认人怎么办 3个月的宝宝认生怎么办 两个月的宝宝睡觉一惊一惊怎么办 六个月宝宝不喜欢喝水怎么办 三岁宝宝尿多怎么办 一岁的宝宝尿少怎么办 一岁宝宝尿黄怎么办 三岁宝宝尿黄怎么办 5个月宝宝认生怎么办 3岁宝宝怕生胆小怎么办 2岁宝宝怕生胆小怎么办 1岁半宝宝认生怎么办 宝宝认人一直哭怎么办 七个月宝宝认人怎么办 一个月宝宝认人怎么办 2个多月宝宝认人怎么办 婴儿认人一直哭怎么办 六个月宝宝认人怎么办 十一个月宝宝断奶后辅食怎么办 6个月宝宝不会坐怎么办 7个月宝宝坐不住怎么办 三个月宝宝白天闹觉怎么办 3个月宝宝不追声怎么办 一岁宝宝垃肚子怎么办 新生儿四天没大便怎么办老放屁 新生儿四五天不大便怎么办 新生儿五天没解大便怎么办 婴儿五天没拉大便怎么办 宝宝45天不拉屎怎么办 儿童4天不大便怎么办 4一5天不大便怎么办 俩月的宝宝便秘怎么办 宝宝6天没大便怎么办 新生儿3天不大便怎么办