yield个人理解及简明示例

1.写法有2种:
yield return <expression>和yield break
yield用于在迭代中返回一个值,并将值带入下一次迭代中。yield break则意味着停止迭代。纯粹的文字描述,一千个人有一千个说法,还是用代码更容易说清楚。
2.官方示例(略带修改):

 private void button1_Click(object sender, EventArgs e)
        {
            string s = string.Empty;
            foreach (int i in List.Power(2,8))
            {
                s += i.ToString() + ",";
            }
            MessageBox.Show(s);
        }
    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;
            }
        }
    }

运行示例,发现power方法中的while代码部分,每循环执行一次,即输出一个值,并将这个值带入下一次循环,而power函数并没有每次被调用。

为了验证,我们修改下官方示例代码,来看看我们的判断是否有误:

private void button1_Click(object sender, EventArgs e)
        {
            string s = string.Empty;
            foreach (int i in List.Power())
            {
                s += i.ToString() + ",";
            }
            MessageBox.Show(s);
        }
    public static IEnumerable Power()
        {
            int counter = 0;
            int result = 1;
            int number = 2, exponent = 8;
            while (counter++ < exponent)
            {
                result = result * number;
                yield return result;
            }
        }

运行结果与官方示例相同,说明.net framework每次只把yield部分所在的部分代码进行了迭代返回处理。

3.官方的另一个示例为用yield作为属性(输出方式略有修改)。

 private void button2_Click(object sender, EventArgs e)
        {
            var theGalaxies = new Galaxies();
            string ps = string.Empty;
            foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
            {
                ps += (theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString() + " >> ");
            }
            MessageBox.Show(ps);
        }
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
        {
            get
            {
                yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
                yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
                yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
                yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
            }

        }

输出结果:

从这个例子可以看出yield其实就是临时中断执行,输出后继续执行而已。

可以修改下这个例子,看效果如何:

 public class Galaxies
    {
        List<Galaxy> ls = new List<Galaxy>();
        public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
        {
            get
            {
                yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
                yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
                yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
                yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
            }

        }
        public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1
        {

            get
            {
                ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 });
                ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 });
                ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 });
                ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 });
                int i = -1;
                while (i++ < ls.Count - 1)
                {
                    yield return ls[i];
                }
            }
        }
    }

调用NextGalaxy1后,结果与官方示例结果相同,还可以进一步修改NextGalaxy1,使其更容易别理解:

 public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1
        {

            get
            {
                ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 });
                ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 });
                ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 });
                ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 });
                int i = 0;
                while (i < ls.Count)
                {
                    yield return ls[i];
                    i++;
                }
            }
        }

这样看来就很容易理解其含义了,更进一步说就是一边给你输出结果,一边继续给你执行代码,一举两得!

如果想中断执行,则直接用yield break即可。

代码如下:

 public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1
        {

            get
            {
                ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 });
                ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 });
                ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 });
                ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 });
                int i = -1;
                while (i++ < ls.Count - 1)
                {
                    yield return ls[i];
                    if (ls[i].MegaLightYears == 0)
                    {
                        yield break;
                    }

                }
            }
        }

输出结果为:

附官方链接:http://msdn.microsoft.com/zh-cn/library/9k7k7cf0.aspx

yield个人理解及简明示例

时间: 2024-09-30 19:15:03

yield个人理解及简明示例的相关文章

响应式布局简明示例

响应式布局简明示例,响应式布局最好同时也是自适应布局,然后再配合css3媒体查询,来达到完美的响应式布局.css3的媒体查询ie9一下是不支持的,这太遗憾了,不过幸运的是有大神已经为前端屌丝们写好了用于IE9以下的媒体查询脚本文件,引用方式如下:<!--[if lt IE 9]>    <script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js">&

C#中yield关键字理解

yield关键字之前用得较少,但是在做项目开发的过程中也遇到了,当时有点迷惑,就顺便研究学习了一下,以下是个人理解,不到之处欢迎拍砖!废话就到这,上代码: class Program { static void Main(string[] args) { string[] strs = new string[] { "1", "2", "3", "4" }; foreach (var item in GetInts(strs)

对yield 的理解

最近在学习Python的时候看到yield的相关语法,感觉很独特,相比其他如C/C++的语法比较有意思,于是在看完资料相关章节做一个总结. yield 是一个类似于 return的语法,但是对于return 而言,在其执行之后,意味着将数据返回给调用者,子程序结束,但是yield却不一样,它能够继续执行,直到下一个yield 转交执行权,之后又可以进入继续执行,周而复始,直到抛出异常. for in range()是一个简单有用的循环,之前的学习知道range()返回的是一个对象,有惰性求值的特

iOS开发——响应链(Responder Chain)的深入理解和代码示例

我在之前一篇博客<iOS响应者链Responder Chain浅析>中对iOS开发中遇到的响应者链概念有了基本的了解.但是仅仅停留在理解概念的基础上还是远远不够的.该博客我们会通过代码案例来深入理解响应链.该博客的示例上传至 https://github.com/chenyufeng1991/ResponderChain  . (1)首先来说说第一响应者(First Responder).响应事件的传递过程就是为了找到第一响应者.以下几个方法: isFirstResponder:判断该View

Redis命令简明示例

一.string命令示例: 1. SET/GET/APPEND/STRLEN: /> redis-cli   #执行Redis客户端工具. redis 127.0.0.1:6379> exists mykey                   #判断该键是否存在,存在返回1,否则返回0. (integer) 0 redis 127.0.0.1:6379> append mykey "hello"      #该键并不存在,因此append命令返回当前Value的长度

yield 的理解

最近在学习Python的时候看到yield的相关语法,感觉很独特,相比其他如C/C++的语法比较有意思,于是在看完资料相关章节做一个总结. yield 是一个类似于 return的语法,但是对于return 而言,在其执行之后,意味着将数据返回给调用者,子程序结束,但是yield却不一样,它能够继续执行,直到下一个yield 转交执行权,之后又可以进入继续执行,周而复始,直到抛出异常. for in range()是一个简单有用的循环,之前的学习知道range()返回的是一个对象,有惰性求值的特

python中generator;对yield的理解

最近学到python的协程的时候,对于yield就是没理解清楚,后来查到资料之后明白了,定义函数里面有yield语句则就是g=callable()就成为了一个generator,其实yield就类似于return语句,暂停执行并返回值,当generator调用这个值之后,它就没有这个值了,具体可以参考https://blog.csdn.net/mieleizhi0522/article/details/82142856 原文地址:https://www.cnblogs.com/pason-blo

对线程中断,join,yield的理解

一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果. 所以你看到Thread.suspend, Thread.stop等方法都被Deprecated了 那么不能直接把一个线程搞挂掉, 但有时候又有必要让一个线程死掉, 或者让它结束某种等待的状态 该怎么办呢? 优雅的方法就是, 给那个线程一个中断信号, 让它自己决定该怎么办. 比如说, 在某个子线程中为了等待一些特定条件的到来, 你调用了Thread.sleep(10000), 预期线程睡10秒之后自己醒

【转】CXF+Spring+Eclipse简明示例

Eclipse+CXF+Spring共同开发的示例,供大家赏鉴. 多系统(异构系统)进行交互时,一种良好的方式便是调用Web Service,本示例基于Apache组织的CXF,为了方便起见特将服务端和客户端写在同一个工程下,实际项目中是不可能的,但是客户端却依赖于服务端的Web Service接口,那么可以通过导出jar的方式. 环境:Eclipse Mars.1 Release (4.5.1)JDK 1.7.0_15Tomcat 7CXF 2.1.3 Spring3 示例项目结构图: 如上图