例子:在不使用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. 【Moment.js】

    Moment.js Moment.js中文网 var moment = require('moment') moment.locale('zh-cn') /* 九月 13日 2015, 4:45:25 ...

  2. VM Depot 助您使用本地开源软件架设开发 Web 站点

     发布于 2014-04-25 作者 云 浪生 使用 VM Depot 中的镜像在 Azure 上创建.开发.部署网站与应用不仅方便快捷而且省时省力!感谢开源社区的大力支持,我们的VM Depot ...

  3. StringHelpers

    public class StringHelpers { public const char QUERY_STRING_DELIMITER = '&'; private static Rijn ...

  4. 将access数据转换成oracle数据

    1.打开access数据文件,选择需转换的表/导出/ODBC数据库 2.输入导出的表名 3.选择数据源,点击新建 4.选择数据源驱动程序 5.保存DSN文件 6.下一步,输入oracle的SERVIC ...

  5. python 零散记录(七)(上) 面向对象 类 类的私有化

    python面向对象的三大特性: 多态,封装,继承 多态: 在不知道对象到底是什么类型.又想对其做一些操作时,就会用到多态 如 'abc'.count('a') #对字符串使用count函数返回a的数 ...

  6. 树中是否存在路径和为 sum leecode java

    https://oj.leetcode.com/problems/path-sum/ /** * Definition for binary tree * public class TreeNode ...

  7. 筛1-n中每个数的因子(nlogn)

    void get_div() //筛因子 { ; i<maxn; i++) for(int j=i; j<maxn; j+=i) dx[j].push_back(i); }

  8. hdoj 4006 The kth great number【优先队列】

    The kth great number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Oth ...

  9. Hadoop: the definitive guide 第三版 拾遗 第十二章 之Hive初步

    Hive简介 Hive是建立在 Hadoop 上的数据仓库基础构架.它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储.查询和分析存储在 Hadoop 中的大规模数据的机制 ...

  10. hdu 4712 (随机算法)

    第一次听说随机算法,在给的n组数据间随机取两个组比较,当随机次数达到一定量时,答案就出来了. #include<stdio.h> #include<stdlib.h> #inc ...