本篇将围绕 《试试 IEnumerable 的 10 个小例子》和《试试 IEnumerable 的另外 6 个小例子》给出的例子,总结一下对于 IEnumerable 接口的一些使用方法,希望读者能够从中获得一些启发。

框架类型的迭代

对于一个实现了 IEnumerable 接口的类型来说,开发中最常用的,就是把这个类型的对象放入到 foreach 等循环关键词中进行迭代,遍历其中的元素进行处理。

这种遍历通常分为两种目的:遍历和查找。

IEnumerable 及其泛型版本 IEnumerable<T> 定义了一个类型的 “可迭代性”。这点很容易理解,系统中的很多集合类型都实现了该接口。

因此这些集合类型均可以采用 foreach 进行迭代遍历。但是每个集合类型的迭代方式和结果是不完全相同的,这取决于集合本身的特性。例如:

  • List<>Stack<> 和 Queue<> 的迭代的顺序不相同,因为数据结构本身要求是不同的
  • ConcurrentDictionary<,> 和 Dictionary<,> 在迭代时的线程安全性是不同的,因为针对线程安全的设计是不同的
  • BlockingCollection.GetConsumingEnumerable 方法返回一个会产生阻塞的消费者对象,

所以,即使都是丢进 foreach,但是效果也是不完全一样的。使用这些,需要读者对这些类型本身需要增进了解。

建议读者在使用框架中实现了 IEnumerable 的类型时,一定要注意迭代的细节,可以通过 MSDN 上的文档了解其特殊性。

Linq

Linq 是一个说小不小的话题,这里只是说其中的 Linq To Object 部分内容。

通过 Linq 中提供的一些扩展方法,可以方便的控制对于一个 IEnumerable 对象的迭代方式。通过这些方法的应用,可以在很多时候避免复杂的条件和循环嵌套。

同时,Linq 中抽象的 Func 和 Action,也要求开发人员在平时的编写过程中注意对于迭代本身的归类和整理。Where(IsLeapYear) 会比 Where(x=>(x % 4 == 0 && x % 100 != 0) || x % 400 == 0) 来的更加容易阅读。

设计复杂的数据结构及其迭代算法

除了基础的数据结构,开发过程中有时需要自定义一些集合类型。这些集合类型需要自己实现一个迭代过程。例如:二叉树及其遍历,对列表进行分页等等。

这些数据结构的迭代通常需要特定算法的支持。

在《试试 IEnumerable 的另外 6 个小例子》中关于树的几个例子便数据此类中。

本地函数

在 C#7.0 引入了本地函数之后, IEnumerable 结合本地函数,快速实现自定义迭代过程的奇怪操作也就跟着出现。

通过这种操作可以在一个函数内采用一些以前不容易实现的方式实现一些操作:

  • 将多重循环拉平
  • 将多级条件判断变为循环判断
  • 无需创建新的类就能快速生成一个上下文需要的特殊迭代算法

这相关的例子在《试试 IEnumerable 的 10 个小例子》中较多。

按照月老板的名言:“业务复杂度是不会因为系统设计变化而减少的,它只是从一个地方转移到了另外的地方。”,我们可以知道,这种写法其实没有使得原来就有的判断和循环变少。只是改变了语法结构。

读者可以将这种操作作为一种 “语法糖” 进行使用。如果是在团队项目中,则需要尊重团队成员的共同意见,因为这种操作并非所有人都愿意接受。

当然,这种做法在一些地方会产生好处。例如在将本地函数、IEnumerable 和 Task 相结合的 T10 测试网络连接 中。这种写法就减少了传统写法中需要创建一个 List 或者 Array 的开销。

总之,这种写法,提供了一种新的思路。是否一定要使用,将取决于读者团队的接受程度。

异步迭代器

在 C# 8 和 .netcore 3.0 到来的版本中,我们迎接到了 IAsyncEnumerable 接口来实现异步迭代器的功能。

IEnumerable 是同步方法的迭代器,IAsyncEnumerable 可以看做是其异步版本。有了这个接口,那么在迭代的过程中也可以充分利用 async/await 带来的编程快感。

本系列中没有添加这部分的示例,但是主体思路是一致的。

她的出现,只会使得开发者更容易应用以上总结的几种主要场景。

详细的例子,可以参见相关文章进行了解

总结

本系列到此便结束了,希望读者多在实践中体会以上总结的几种使用场景。

本系列中的例子已经全部使用 dotnetfiddle.net 进行了重写,读者可以直接在本博客的页面上运行这些示例。

如果无法正常的展示示例,读者也可以通过本仓库下载示例相关的代码

总结一下 IEnumerable 的例子的更多相关文章

  1. IEnumerable和IQueryable的区别以及背后的ExpressionTree表达式树

    关于IEnumerable和IQueryable的区别,这事还要从泛型委托Func<T>说起.来看一个简单的泛型委托例子: class Program { static void Main ...

  2. C#版的MapReduce

    如果不知道MapReduce是怎么工作的,请看这里,如果不知道MapReduce是什么,请google之! 今天“闲”来无事,忽想起C#里没有MapReduce的方法,构思之,coding之: #re ...

  3. C# 枚举器

    1:枚举器和可枚举类型 我们知道使用foreach可以遍历数组中的元素.那么为什么数组可以被foreach语句处理呢,下面我们就进行讨论一下这个问题. 2:使用foreach语句 我们知道当我们使用f ...

  4. 试试 IEnumerable 的 10 个小例子

    IEnumerable 接口是 C# 开发过程中非常重要的接口,对于其特性和用法的了解是十分必要的.本文将通过10个小例子,来熟悉一下其简单的用法. 全是源码 以下便是这10个小例子,响应的说明均标记 ...

  5. 试试 IEnumerable 的另外 6 个小例子

    IEnumerable 接口是 C# 开发过程中非常重要的接口,对于其特性和用法的了解是十分必要的.本文将通过6个小例子,来熟悉一下其简单的用法. <!-- more --> 阅读建议 在 ...

  6. 为IEnumerable<T>添加RemoveAll<IEnumerable<T>>扩展方法--高性能篇

    最近写代码,遇到一个问题,微软基于List<T>自带的方法是public bool Remove(T item);,可是有时候我们可能会用到诸如RemoveAll<IEnumerab ...

  7. C# 索引器,实现IEnumerable接口的GetEnumerator()方法

    当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...

  8. 你可能不知道的陷阱, IEnumerable接口

    1.  IEnumerable 与  IEnumerator IEnumerable枚举器接口的重要性,说一万句话都不过分.几乎所有集合都实现了这个接口,Linq的核心也依赖于这个万能的接口.C语言的 ...

  9. .NET面试题系列[10] - IEnumerable的派生类

    .NET面试题系列目录 IEnumerable分为两个版本:泛型的和非泛型的.IEnumerable只有一个方法GetEnumerator.如果你只需要数据而不打算修改它,不打算为集合插入或删除任何成 ...

随机推荐

  1. CS184.1X 计算机图形学导论L3V2和L3V3(部分)

    组合变换 连接矩阵的优点是可以使用这些矩阵单独操作. 多个变换依然是一个矩阵. 连接矩阵不可交换,因为矩阵乘法不具有交换性. X3=RX2 X2=SX1 X3=R(SX1)=(RS)X1 X3≠SRX ...

  2. Jenkins介绍

    持续集成: 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证 ...

  3. Redis原理篇

    Redis原理篇 1.发布 订阅模式 1.1列表 的局限 ​ 前面我们说通过队列的 rpush 和 lpop 可以实现消息队列(队尾进队头出),但是消费者需要不停地调用 lpop 查看 List 中是 ...

  4. CSP2019 考前复习

    动态规划 [NOIP2016]愤怒的小鸟(状压+思维) 多组数据题 共有i只猪,给出每只猪的坐标,鸟的飞行轨迹为经过原点的抛物线,求最少要多少只鸟能消灭所有的猪 \[ 猪数量n<=18 \] 看 ...

  5. Cocos Creator实现1024游戏,免费提供代码。

    效果预览 ​ 获取代码 私信或留言.  游戏介绍 ● Github上的代码,不能进行合并操作,修改以后,功能类似2048,空白块赏随机位置,生成2,可以往左.右.上.下滑动,数字会朝着指定方向运动,相 ...

  6. 我的Python学习方向-前端辅助-后端框架django学习-浅谈(一)

    初始python,很直观的感受是编译格式多样,代码简介易懂 作为一门通用编程语言,python能编写多种用途的编程语言,当然对于我目前,我的方向便是借助其前端编辑器,实现后台框架的连接学习 1.首先便 ...

  7. SpringBoot-Mysql模板多数据源加载

    SpringBoot-Mysql模板多数据源加载 qq交流群: 812321371 微信交流群: MercyYao 简介 在 java 项目里常用到 mysql 多数据源操作.结合 springboo ...

  8. nsq (三) 消息传输的可靠性和持久化[一]

    上两篇帖子主要说了一下nsq的拓扑结构,如何进行故障处理和横向扩展,保证了客户端和服务端的长连接,连接保持了,就要传输数据了,nsq如何保证消息被订阅者消费,如何保证消息不丢失,就是今天要阐述的内容. ...

  9. oc基本知识

    (一)构造函数 h文件 #import <Foundation/Foundation.h> @interface Student : NSObject { NSString *_name; ...

  10. unity 导出模型

    不论unity是否运行,到处其中的模型方法: 1.如下图建立相关文件目录,并建立如下脚本 2.脚本代码 using UnityEngine; using UnityEditor; using Syst ...