登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
导读
排行榜
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
小组
VIP申请
VIP网盘
网盘
联系我们
发帖说明
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
先说IEnumerable,我们每天用的foreach你真的懂它吗? ...
先说IEnumerable,我们每天用的foreach你真的懂它吗?
[ 复制链接 ]
站竣凰
2025-5-29 00:11:43
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
我们先思考几个问题:
为什么在foreach中不能修改item的值?
要实现foreach需要满足什么条件?
为什么Linq to Object中要返回IEnumerable?
接下来,先开始我们的正文。
自己实现迭代器
.net中迭代器是通过IEnumerable和IEnumerator接口来实现的,今天我们也来依葫芦画瓢。
首先来看看这两个接口的定义:
并没有想象的那么复杂。其中IEnumerable只有一个返回IEnumerator的GetEnumerator方法。而IEnumerator中有两个方法加一个属性。
接下来开发画瓢,我们继承IEnumerable接口并实现:
下面使用原始的方式调用:
有朋友开始说了,我们平时都是通过foreache来取值的,没有这样使用过啊。好吧,我们来使用foreach循环:
为什么说基本上是等效的呢?我们先看打印结果,在看反编译代码。
由此可见,两者有这么个关系:
我们可以回答第一个问题了“为什么在foreach中不能修改item的值?”:
我们还记得IEnumerator的定义吗
接口的定义就只有get没有set。所以我们在foreach中不能修改item的值。
我们再来回答第二个问题:“要实现foreach需要满足什么条件?”:
必须实现IEnumerable接口?
NO
我们自己写的MyIEnumerable删掉后面的IEnumerable接口一样可以foreach(不信?自己去测试)。
所以要可以foreach只需要对象定义了GetEnumerator无参方法,并且返回值是IEnumerator或其对应的泛型。细看下图:
也就是说,只要可以满足这三步调用即可。不一定要继承于IEnumerable。有意思吧!
下次面试官问你的时候一定要争个死去活来啊,哈哈!
yield的使用
你肯定发现了我们自己去实现IEnumerator接口还是有些许麻烦,并且上面的代码肯定是不够健壮。对的,.net给我们提供了更好的方式。
你会发现我们连MyIEnumerator都没要了,也可以正常运行。太神奇了。yield到底为我们做了什么呢?
好家伙,我们之前写的那一大坨。你一个yield关键字就搞定了。最妙的是这块代码:
这就是所谓的状态机吧!
我们继续来看GetEnumerator的定义和调用:
我们调用GetEnumerator的时候,看似里面for循环了一次,其实这个时候没有做任何操作。只有调用MoveNext的时候才会对应调用for循环:
现在我想可以回答你“为什么Linq to Object中要返回IEnumerable?”:
因为IEnumerable是
延迟加载
的,每次访问的时候才取值。也就是我们
在Lambda里面写的where、select并没有循环遍历(只是在组装条件)
,只有在ToList或foreache的时候才真正去集合取值了。这样大大提高了性能。
如:
这个时候得到了就是IEnumerable对象,但是没有去任何遍历的操作。(对照上面的gif动图看)
什么,你还是不信?那我们再来做个实验,自己实现MyWhere:
现在看到了吧。执行到MyWhere的时候什么动作都没有(
返回的就是IEnumerable
),只有执行到ToList的时候才代码才真正的去遍历筛选。
这里的MyWhere其实可以用扩展方法来实现,提升逼格。(Linq的那些查询操作符就是以扩展的形式实现的)[了解扩展方法]。
怎样高性能的
随机
取IEnumerable中的值
这段代码来源《深入理解C#》,个人觉得非常妙。贴出来给大家欣赏哈。
结束:
demo下载:http://pan.baidu.com/s/1dE94c1b
接下篇:《再讲IQueryable,揭开表达式树的神秘面纱》
本文以同步至《C#基础知识巩固系列》
来源:新程序网络收集,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
先说
IEnumerable
我们
每天
用的
相关帖子
2025年国内外常用的28款BT磁力下载工具推荐:老司机必备!
算起计算器APP—好看好用的多功能计算器
吐血推荐!6款超好用的AI论文写作工具
工作中最常用的6种API网关
在自动化测试时,Python常用的几个加密算法,你有用到吗
Debian 12/13可用的华宇拼音输入法
从一次分表实践谈起:我们真的需要复杂的分布式ID吗?
有用的包 #Python
vue 常用的 gantt 甘特图组件推荐
最新常用的js跳转代码
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
安全
2025年国内外常用的28款BT磁力下载工具推荐:老司机必备!
2
703
姬宜欣
2025-11-08
业界
算起计算器APP—好看好用的多功能计算器
2
40
曲愍糙
2025-11-08
安全
吐血推荐!6款超好用的AI论文写作工具
2
933
柯惠心
2025-11-09
业界
工作中最常用的6种API网关
2
554
支季雅
2025-11-18
安全
在自动化测试时,Python常用的几个加密算法,你有用到吗
1
865
厂潺
2025-11-18
安全
Debian 12/13可用的华宇拼音输入法
4
745
锺冰洁
2025-11-20
业界
从一次分表实践谈起:我们真的需要复杂的分布式ID吗?
2
1045
杭环
2025-11-20
业界
有用的包 #Python
3
885
茅断卉
2025-12-07
代码
vue 常用的 gantt 甘特图组件推荐
0
684
柴古香
2025-12-09
代码
最新常用的js跳转代码
0
4
新程序
2025-12-11
回复
(2)
雌鲳签
4 天前
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
感谢分享
缀访
昨天 08:52
回复
使用道具
举报
照妖镜
程序园永久vip申请,500美金$,无限下载程序园所有程序/软件/数据/等
感谢分享
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
站竣凰
昨天 08:52
关注
0
粉丝关注
29
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
anyue1937
9994893
kk14977
6845356
3934307807
991123
4
xiangqian
638210
5
宋子
9984
6
韶又彤
9999
7
闰咄阅
9993
8
刎唇
9993
9
俞瑛瑶
9998
10
蓬森莉
9951
查看更多