yieId浅谈
例子:在不使用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浅谈的更多相关文章
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- Linux特殊符号浅谈
Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...
- 浅谈Angular的 $q, defer, promise
浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00 博客园-原创精华区 原文 http://www.cnblogs.com/big-snow/ ...
随机推荐
- How to Create a SharePoint 2010 Project Without SharePoint Server
转:http://community.bamboosolutions.com/blogs/sharepoint-2010/archive/2012/06/21/create-a-sharepoint- ...
- Android Loader详解二:使用加载器
一个使用装载器的应用会典型的包含如下组件: 一个Activity或Fragment. 一个LoaderManager的实例. 一个加载被ContentProvider所支持的数据的CursorLoad ...
- 迷宫城堡--HDOJ 1269
迷宫城堡 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDOJ/HDU 1256 画8(绞下思维~水题)
Problem Description 谁画8画的好,画的快,今后就发的快,学业发达,事业发达,祝大家发,发,发. Input 输入的第一行为一个整数N,表示后面有N组数据. 每组数据中有一个字符和一 ...
- bzoj 4016 [FJOI2014]最短路径树问题(最短路径树+树分治)
4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 426 Solved: 147[Submit][Stat ...
- 《University Calculus》-chape6-定积分的应用-求体积
定积分一个广泛的应用就是在求解一些“看似不规则”的几何体的体积,之所以说看似不规则,是因为不规则之下还是有一定的“规则性”可言的,我们就是需要抓住这些线索进行积分运算得到体积. 方法1:切片法. 这里 ...
- 1 weekend110的Linux带图形系统安装 + 网络配置 + 静态IP设置
一.weekend110的Linux带图形系统安装 二.网络配置 明明是配置好的啊,只能说是域名出现问题了, 出现ping:unknow host www.baidu.com的问题解决 解决Ubunt ...
- 事物复制中大项目(Large Article)出问题如何快速修复
事物日志中如果大的发布项目(Article)出问题了,并且影响了系统的使用,如何快速的解决? 一般的做法是重新用快照或者备份初始化,但是如果出问题的表非常大(上亿的记录,几十GB的数据),使用初始化是 ...
- springsecurity4+springboot 实现remember-me 发现springsecurity 的BUG
前言:现在开发中,记住我这个功能是普遍的,用户不可能每次登录都要输入用户名密码.昨天准备用spring security的记住我功能,各种坑啊,吐血 . 先看下具体实现吧. spring securi ...
- SpringMVC接收页面表单参数(转)
作者:CN.programmer.Luxh 和java相关 一个普通的表单. 表单的代码如下: <%@ page language="java" contentType=&q ...