例子:在不使用yieId时,通常我们都会采取先遍历再把元素加到新的List中

            using (var reader = SqlHelper.ExecuteReader(""))
{
if (reader.HasRows)
{
IList<Captcha> list = new List<Captcha>();
while (reader.Read())
{
list.Add(SqlHelper.MapEntity<Captcha>(reader));
}
return list;
}
}
return null;

接下来我们用它(yieId)来改善以上代码:

using (var reader = SqlHelper.ExecuteReader(""))
{
if (reader.HasRows)
{ while (reader.Read())
{
yield return SqlHelper.MapEntity<Captcha>(reader);
} }
}

这里需要注意的是在使用yieId时,返回值类型必须为IEnumerable

现在我们简单介绍下yieId,先分享一个错误的理解,注意 是错误的理解

根据上图,我们定义一个变量作用域然后开辟一个List变量,在代码执行的过程中都通过这个List来Add这个元素。最后返回这个新的List。这可以当成我们对yieId的初步理解,但yieId绝对不是那么简单的。

我们来写一个简单的Demo,让您更快的理解yieId。

如题:定义一个string数组,然后将这个数组转换成Int数组

string[] strs = new string[] { "", "", "" };

比较普遍的处理方式就是遍历这些元素添加到一个新的数组里,至于代码怎么实现这里就不讲了。今天的重点是如何通过yieId来更高效的实现这个效果

首先我们来定一个一个静态类并且返回值类型为IEnumerable的方法:

static IEnumerable<int> GetInts(string[] strs)
{ foreach (var item in strs)
{
yield return Convert.ToInt32(item);
}
}

当然,这里用linq来实现将回更简洁,不过这不是咱们今天的话题,就不聊它了。

以上代码就如上图所说,先开辟一个临时空间,再通过yieId return把数据丢到这个临时空间中。最后把临时空间的数据全部放进去

string[] strs = new string[] { "", "", "" };
int[] ints = GetInts(strs).ToArray();
foreach (var item in ints)
{
Console.WriteLine(item.GetType());
}
Console.ReadKey();

为了让大伙能看的更明白,我这边使用GetType(),以便有效的让您知道读出来的数据类型是否准确

这样,移掉GetType()就能直接得到1,2,3 的结果了


到这边,我想您应该对yieId有一个自己的初步理解了吧?接下来我们来分析下yieId带给我们的好处。

1.代码更精简 (这个刚才您应该有体会到了)

除此之外还有一个特点,我们来改动之前的这一段代码:

static void Main(string[] args)
{
string[] strs = new string[] { "", "", "" };
int[] ints = GetInts(strs).ToArray();
foreach (var item in ints)
{
Console.WriteLine(item.GetType());
}
Console.ReadKey();
}
static IEnumerable<int> GetInts(string[] strs)
{ foreach (var item in strs)
{
Console.WriteLine(item.GetType());//改动1
yield return Convert.ToInt32(item);
}
}

请思考这个执行出来的结果会是怎么样的呢?(先自动屏蔽下图哦)

这个结果还是合情合理的,在调用GetInts()时,数组的类型还是String,并且调用3次。再执行遍历,转换成Int类型,结果刚好是3个string 3个int。

那为什么会是3个string 3个int了,原因是因为我们调用了.ToArray()这个方法,我们尝试把这个方法去掉。但这时我们需要改变被转换的变量的返回值类型

 IEnumerable<int> ints = GetInts(strs);

执行结果:

对于这个执行结果,就开始有点好奇了。怎么会是这样呢?我们来研究下yieId到底发挥了什么效果。

根据上图,在调试的过程中我们发现,在执行F11(逐语句)时,并不会跑到GetInts()这个方法体中来。那就说白了,当我们在使用yieId return的时候,它并没有真正的被执行。

当我们执行foreach遍历的时候,这个ints的变量事先会去调用GetEnumerator()这个方法来拿到这个迭代器,然后通过这个迭代器去迭代的时候,就像去读这个数组的时候遍历最后才调用这个GetInts(),

就像一个指针去搜寻每一个元素一样。另外,在调试中,当yieId return后,yieId会将这个方法体进行冻结。当需要继续执行的时,会根据遍历的次数来继续执行。这时指针会继续往下移动一位。

这时,我们回到之前用List去实现这样的效果,从代码执行上来看。就会浪费了很多不需要的循环。在使用yieId后,我们可以有效的去处理这个代码执行效率的问题,我们在遍历这个ints时,加一层判断

 if (item > )
break;

这样当不满足条件时,就不会去使用它(GetInts())这个方法,相当于它自动被冻结住了。我们看一下执行结果:

这就是yieId的好处,能很好的提高代码执行效率。有很多人几乎都没接触甚至根本不知道这个东西的存在,其实个人认为只是因为我们所见到的市场代码质量不是很高。其实只要你去看一些比较著名的开源项目,比如EF,那里面都会大量使用到这个yieId关键词,包括MVC的源码里也很多。

yieId浅谈的更多相关文章

  1. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  2. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  3. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  4. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  5. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  6. 浅谈angular2+ionic2

    浅谈angular2+ionic2   前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别.   1. 项目所用:angular2+ionic2 ...

  7. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  8. Linux特殊符号浅谈

    Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...

  9. 浅谈Angular的 $q, defer, promise

    浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00  博客园-原创精华区 原文  http://www.cnblogs.com/big-snow/ ...

随机推荐

  1. Remarks on a preprint

    Page 2 Line 1, "reads" should be "read". Page 2 Line 5, "are initial veloci ...

  2. 还能输入多少字?(JS动态计算)

    <div class="m-form ovh"> <div class="hd"> <span class="fr&qu ...

  3. [转]NHibernate之旅(5):探索Insert, Update, Delete操作

    本节内容 操作数据概述 1.新建对象 2.删除对象 3.更新对象 4.保存更新对象 结语 操作数据概述 我们常常所说的一个工作单元,通常是执行1个或多个操作,对这些操作要么提交要么放弃/回滚.想想使用 ...

  4. python 默认的系统编码 sys.setdefaultencoding

    python2.x的编码问题有时让人很头疼,一会ascii,一会unicode. 在脚本里多见这样的操作: import sys reload(sys) sys.setdefaultencoding( ...

  5. Poj 2299 - Ultra-QuickSort 离散化,树状数组,逆序对

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 52306   Accepted: 19194 ...

  6. myeclipse输入“.”后没有自动提示功能

    今天和室友安装了一样的myeclipse版本,结果室友的自动提示功能有,我的输入"."后却不能提示,这对我们敲代码简直来说是一个折磨,不能自动提示,本来还以为是系统问题,一个是wi ...

  7. jetty之安装,配置,部署,运行

    上篇文章中详解了关于什么是jetty,后续文章主要是介绍jetty的使用.本章介绍jetty环境的配置及部署war包. 1. 安装 1. 先下载一个jetty的压缩包,下载地址:http://www. ...

  8. W5500问题集锦(持续更新中)

    在"WIZnet杯"以太网技术竞赛中,有非常多參赛者在使用中对W5500有各种各样的疑问,对于这款WIZnet新推出的以太网芯片,使用中大家是不是也一样存在下面问题呢?来看一看: ...

  9. Apache Solr配置

    Solr配置 Solr的主要功能是全文检索,该功能分为两个过程:创建索引和对索引进行搜索: 在创建索引之前,需要重点关注两个配置文件:SOLR_HOME/collection1/conf/schema ...

  10. 动态规划入门——Eddy's research II

    转载请注明出处:http://blog.csdn.net/a1dark 分析:找规律 #include<stdio.h> int main(){ int m,n; while(scanf( ...