随心所欲~我也做个集合遍历器吧(自己的foreach,委托的威力)
感觉微软在面向对象三大原则中,封装性运用的最为突出,它会将一些复杂的算法,结构,功能代码进行封装,让程序员在使用时十分得心应手,如关键字里的foreach和labmda表达式里的Foreach等等,今天我也来写一个集合遍历器得了,呵呵。
小知识:你的集合如果是List,那么它里面的N多方法都是可以拿来就用的,今天的遍历功能,使用List里的GetEnumerator()方法实现,它返回的其实是一个Enumerator结果体,这个枚举器的结构体如下:
[Serializable]
public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
{ // 摘要:
// 获取枚举数当前位置的元素。
//
// 返回结果:
// System.Collections.Generic.List<T> 中位于该枚举数当前位置的元素。
public T Current { get; } // 摘要:
// 释放由 System.Collections.Generic.List<T>.Enumerator 使用的所有资源。
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public void Dispose();
//
// 摘要:
// 使枚举数前进到 System.Collections.Generic.List<T> 的下一个元素。
//
// 返回结果:
// 如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。
//
// 异常:
// System.InvalidOperationException:
// 在创建了枚举数后集合被修改了。
public bool MoveNext();
}
它有一个属性Current和一个方法MoveNext,这是我们实现遍历器的前提,Current属性会把当前值输出,而MoveNext会将集合指向下一个元素,它的返回值为bool类型,true表示有下一个元素,false表示集合已经被遍历完了。
有了上面的知识,我们再配合委托Action<T>,就可以设计一个自己的foreach方法了,呵呵
/// <summary>
/// 占占枚举遍历器
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="action"></param>
static void ForeachZzl<T>(IList<T> list, Action<T> action)
{
var e = list.GetEnumerator(); while (e.MoveNext())
{
action(e.Current);
}
}
调用这个方法也很简单,由于使用了委托,所以,只要保正你有一个输入参数T,就可以运用到所有方法体上了
List<string> enums = new List<string> { "", "", "", "", "" };
ForeachZzl(enums, i =>
{
Console.WriteLine(i);
});
怎么样,是不是有点向微软自己的Foreach这个lambda呀,呵呵,其实我们加个扩展方法,它就变成了lambda了,看代码
/// <summary>
/// 扩展方法要写在静态类里,方法也为静态方法(非静态方法不能写在静态类里,呵呵)
/// </summary>
public static class ExtensionFunction
{
public static void ForeachZzl<T>(this IList<T> list, Action<T> action)
{
var e = list.GetEnumerator(); while (e.MoveNext())
{
action(e.Current);
}
}
}
下面这种形式的调用是不是就很熟悉了,呵呵
enums.ForeachZzl(i =>
{
Console.WriteLine(i);
});
通过这篇文章,我们可以完全领略到委托的威力,呵呵。
随心所欲~我也做个集合遍历器吧(自己的foreach,委托的威力)的更多相关文章
- .NET 中创建支持集合初始化器的类型
对象初始化器和集合初始化器只是语法糖,但是能让你的代码看起来更加清晰.至少能让对象初始化的代码和其他业务执行的代码分开,可读性会好一些. 本文将编写一个类型,可以使用集合初始化器构造这个类型.不只是添 ...
- 疑问:Iterator 遍历器和数据集合各种遍历方法的区别
https://es6.ruanyifeng.com/#docs/iterator Iterator(遍历器)的概念 Iterator 接口主要供for...of消费 Iterator 的遍历过程是: ...
- 两种QMultiMap的遍历方法(最好使用只读遍历器)
留个爪,备查 QMultiMap<QString, QString>& remote_map = my_obj->m_MapVersion; // ccc 这里体现了引用的好 ...
- 【前端】【javascript】es6中的遍历器接口Iterator
好久没发文章啦-.-为了证明我还活着,我决定从笔记里面抓一篇还算不乱比较像文章的发出来... 这些笔记是我在学es6的时候断断续续记录的,最近会一份一份整理陆陆续续发出来,顺便也自己再看一遍.我学习e ...
- IOS各种集合遍历效率对比
前言: 对于ios项目开发中总会遇见各种集合遍历,出于对各种遍历效率的好奇心,所以准备写个测试程序测试一下 首先:先声明一个NSMutableArray,测试数据量分别是1000条,10000条,10 ...
- iOS学习16之OC集合遍历和数组排序
1.集合遍历 1> 遍历 集合(Collection):OC中提供的容器类:数组,字典,集合. 遍历:对集合中元素依次取出的过称叫做遍历. 三种方式:① for循环遍历: ② NSEnumera ...
- OC中几种集合的遍历方法(数组遍历,字典遍历,集合遍历)
// 先分别初始化数组.字典和集合,然后分别用for循环.NSEnumerator枚举器和forin循环这三个方法来实现遍历 NSArray *array = @[@"yinhao" ...
- iOS学习之Object-C语言集合遍历和数组排序
一.集合遍历 1.集合:OC中提供的容器类,数组,字典,集合. 2.遍历:对集合中元素依次取出的过程叫做遍历. 二.for循环遍历 1.通过for循环的循环变量用作数组元 ...
- C#高级知识点概要(3) - 特性、自动属性、对象集合初始化器、扩展方法、Lambda表达式和Linq查询
1.特性(Attributes) 特性(Attributes),MSDN的定义是:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法 ...
随机推荐
- Spring+Spring MVC+MyBatis
Spring+Spring MVC+MyBatis 目录 一.新建一个基于Maven的Web项目 二.创建数据库与表 三.添加依赖包 四.新建POJO实体层 五.新建MyBatis SQL映射层 六. ...
- Oracle EBS-SQL (BOM-9):检查系统BOM总数.sql
SELECT ITM.SEGMENT1 物料编码 ,ITM.DESCRIPTION 物料描述 ...
- MyGui笔记(1)建立第一个工程
记录下学习 MyGui的一些笔记,从建立第一个工程开始. 步骤: 1.右键MYGUI解决方案,添加→新建项目,选择“Win32 项目”,名称为:TestHello.下一步,勾选“空项目”. 2.设置工 ...
- 任务管理器进程中多个chrome.exe的问题
偶然发现任务管理器进程中有多个chrome.exe进程,非常奇怪自己仅仅打开了一次浏览器,为什么会有多个?! 上网一查才发现:原来使用Google浏览器Google Chrome每开一个新标签页面,都 ...
- HNU 12850 Garage
长为H的格子里面放n个长为h的格子 最多会有n+1个空隙 要使每一个空隙长度都小于h (H-h*n)/(n+1)<h n>(H/h-1)/2 #include<bits/stdc++ ...
- vs2010:【“System.Data.OracleClient.OracleConnection”已过时】警告
在oracle 安装目录下 找到 Oracle.DataAccess.dll添加引用,然后 using Oracle.DataAccess.Client;其他的都不用动,即可.连接字符串中 如有 用的 ...
- UCML快速开发平台学习1-UCML环境安装
最近公司项目时间紧张,经过各位大神的PK,决定用多年前话10W采购过来,一直被雪藏的UCML来开发.为啥花了钱买回来不用我就不吐槽了. UCML安装 翻看安装手册,貌似不 ...
- 自定义Toast样式-两行文本居中显示
toast可以设置自定义的view和显示位置.下面是一个简单的例子,复杂些的就是改变其布局文件就可以了. /** * @author BMR * @ClassName: ToastWithTwoTex ...
- C# - ADO.Net 调用存储过程
------------------------存储过程调用,创建DataSet:----------------------//数据库连接字符串string connStr = @"Dat ...
- js实现睡眠
//js暂停函数 function Pause(obj, iMinSecond) { if (window.eventList == null) window.eventList = new Arra ...