using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Linq; namespace Test
{
//C#的yield关键字由来以久,如果我没有记错的话,应该是在C# 2.0中被引入的。
//相信大家此关键字的用法已经了然于胸,很多人也了解yield背后的“延迟赋值”机制。
//但是即使你知道这个机制,你也很容易在不经意间掉入它制造的陷阱。
//
//对于上面的现象,很多人一眼就可以看出这是由于yield背后的“延迟赋值”机制导致,
//但是不可否认我们会不经意间犯这种错误。为了让大家对这个问题有稍微深刻的认识,
//我们还是简单来谈谈“延迟赋值”。延迟赋值(Delay|Lazy Evaluation)又被称为延迟计算。
//为了避免不必要的计算导致的性能损失,和LINQ查询一样,yield关键字并不会导致后值语句的立即执行,
//而是转换成一个“表达式”。只有等到需要的那一刻(进行迭代)的时候,表达式被才被执行。
class Program
{
static void Main(string[] args)
{
IEnumerable<Vector> vectors = GetVectors(); foreach (var vector in vectors)
{
vector.X = ;
vector.Y = ;
} //赋值没成功 还是输出原来的结果
//从运行后的结过我们可以看出,Vector对象被创建了6次,来自于两次迭代。
//一次是对Vector元素的重新赋值,另一次源自对Vector元素的输出。
//由于两次迭代造作的并不是同一批对象,才会导致X和Y属性依然“保持”着原始的值。
foreach (var vector in vectors)
{
Console.WriteLine(vector);
} Console.WriteLine("分割线-------------------------------------------"); IEnumerable<Vector> vectorsNow = GetVectors().ToList();
foreach (var vector in vectorsNow)
{
vector.X = ;
vector.Y = ;
}
foreach (var vector in vectorsNow)
{
Console.WriteLine(vector);
} Console.ReadLine();
} static IEnumerable<Vector> GetVectors()
{
yield return new Vector(, );
yield return new Vector(, );
yield return new Vector(, );
}
} public class Vector
{
public double X { get; set; }
public double Y { get; set; }
public Vector(double x, double y)
{
Console.WriteLine("构造函数");
this.X = x;
this.Y = y;
} public override string ToString()
{
return string.Format("X = {0}, Y = {1}", this.X, this.Y);
}
}
}

C#的yield关键字的更多相关文章

  1. 从yield关键字看IEnumerable和Collection的区别

    C#的yield关键字由来以久,如果我没有记错的话,应该是在C# 2.0中被引入的.相信大家此关键字的用法已经了然于胸,很多人也了解yield背后的“延迟赋值”机制.但是即使你知道这个机制,你也很容易 ...

  2. .NET中的yield关键字

    浅谈yield http://www.cnblogs.com/qlb5626267/archive/2009/05/08/1452517.html .NET中yield关键字的用法 http://bl ...

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

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

  4. 从range和xrange的性能对比到yield关键字(中)

    上节提出了range和xrange的效率问题,这节我们来探究其中的原因   yield的使用   我们看下面的程序: #coding: utf-8 def test(): print 4 print ...

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

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

  6. 转载yield关键字理解

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

  7. yield关键字的用法

    在上一篇文章中,说了下foreach的用法,但是还是比较复杂的,要实现接口才能进行遍历,有没有简单些的方法呢?答案是肯定的.且看下面. yield关键字的用法: 1.为当前类型添加一个任意方法,但是要 ...

  8. yield 关键字和迭代器

    一般使用方法     yield 关键字向编译器指示它所在的方法是迭代器块 在迭代器块中,yield 关键字与 return 关键字结合使用,向枚举器对象提供值. 这是一个返回值,例如,在 forea ...

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

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

随机推荐

  1. 剑指Offer 数值的整数次方

    题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方.   思路: 要考虑边界,0,负数   AC代码: class Solution ...

  2. php使用文件缓存

    使用php读取mysql中的数据很简单,数据量不大的时候,mysql的性能还是不错的.但是有些查询可能比较耗时,这时可以把查询出的结果,缓存起来,减轻mysql的查询压力. 缓存的方法有几种:使用me ...

  3. SVN钩子说明

    post-commit在提交完成,成功创建版本之后执行该钩子,提交已经完成,不可更改,因此本脚本的返回值被忽略. post-lock对文件进行加锁操作之后执行该脚本 post-revprop-chan ...

  4. django的views里面的request对象详解大全

    简介 HTTP 应用的信息是通过 请求报文 和 响应报文 传递的,关于更多的相关知识,可以阅读<HTTP权威指南>获得. 其中 请求报文 由客户端发送,其中包含和许多的信息,而 djang ...

  5. linux awk, xargs

    awk , 很赞的教程:http://coolshell.cn/articles/9070.html xargs, http://blog.csdn.net/andy572633/article/de ...

  6. 【GoLang】golang 面向对象编程 & 面向接口编程

    005.面向对象&接口编程 1 面向函数编程 1.1 将数据作为参数传递到函数入参 1.2 对象与函数是分离的 2 面向对象编程 2.1 使用者看起来函数作为对象的属性而非参数 2.2 函数属 ...

  7. Java总结(二):继承——Inheritance

    关于继承: 1.为了重用代码——引入继承. 2.父类的某些方法反正要被重写,在父类里实现在也无用——引入抽象类. 3.把抽象类里的抽象方法抽出来——引入接口.

  8. C# webservice 编写、发布、调用

    采用的工具VS2010生成工程 1. 生成webservice工程:建 ASP.NET 空WEB 应用程序. 2. 在建好的ASP.NET 空WEB应用程序中新建项“web 服务”. 完成上述内容工程 ...

  9. ios coredata 无任何错误提示crash

    最近写程序是遇到了一种情况,对coredata 操作时,有一定几率crash,crash时无任何说明,断点调试后发现,fetch出的对象的属性竟然和数据库中的不同,不知道什么情况下导致了context ...

  10. 51nod 1065 最小正子段和 (贪心)

    题目:传送门. 题意:中文题. 题解:求前缀和,并且标记每个数的下标,按照前缀和大小进行从小到大排序.随后进行遍历,如果满足下标data[i-1].id<data[i].id&& ...