感觉微软在面向对象三大原则中,封装性运用的最为突出,它会将一些复杂的算法,结构,功能代码进行封装,让程序员在使用时十分得心应手,如关键字里的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,委托的威力)的更多相关文章

  1. .NET 中创建支持集合初始化器的类型

    对象初始化器和集合初始化器只是语法糖,但是能让你的代码看起来更加清晰.至少能让对象初始化的代码和其他业务执行的代码分开,可读性会好一些. 本文将编写一个类型,可以使用集合初始化器构造这个类型.不只是添 ...

  2. 疑问:Iterator 遍历器和数据集合各种遍历方法的区别

    https://es6.ruanyifeng.com/#docs/iterator Iterator(遍历器)的概念 Iterator 接口主要供for...of消费 Iterator 的遍历过程是: ...

  3. 两种QMultiMap的遍历方法(最好使用只读遍历器)

    留个爪,备查 QMultiMap<QString, QString>& remote_map = my_obj->m_MapVersion; // ccc 这里体现了引用的好 ...

  4. 【前端】【javascript】es6中的遍历器接口Iterator

    好久没发文章啦-.-为了证明我还活着,我决定从笔记里面抓一篇还算不乱比较像文章的发出来... 这些笔记是我在学es6的时候断断续续记录的,最近会一份一份整理陆陆续续发出来,顺便也自己再看一遍.我学习e ...

  5. IOS各种集合遍历效率对比

    前言: 对于ios项目开发中总会遇见各种集合遍历,出于对各种遍历效率的好奇心,所以准备写个测试程序测试一下 首先:先声明一个NSMutableArray,测试数据量分别是1000条,10000条,10 ...

  6. iOS学习16之OC集合遍历和数组排序

    1.集合遍历 1> 遍历 集合(Collection):OC中提供的容器类:数组,字典,集合. 遍历:对集合中元素依次取出的过称叫做遍历. 三种方式:① for循环遍历: ② NSEnumera ...

  7. OC中几种集合的遍历方法(数组遍历,字典遍历,集合遍历)

    // 先分别初始化数组.字典和集合,然后分别用for循环.NSEnumerator枚举器和forin循环这三个方法来实现遍历 NSArray *array = @[@"yinhao" ...

  8. iOS学习之Object-C语言集合遍历和数组排序

    一.集合遍历      1.集合:OC中提供的容器类,数组,字典,集合.      2.遍历:对集合中元素依次取出的过程叫做遍历. 二.for循环遍历      1.通过for循环的循环变量用作数组元 ...

  9. C#高级知识点概要(3) - 特性、自动属性、对象集合初始化器、扩展方法、Lambda表达式和Linq查询

    1.特性(Attributes) 特性(Attributes),MSDN的定义是:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法 ...

随机推荐

  1. C99新特性

    c99标准允许使用变长数组,变的意思是可以根据变量的值来指定数组的维数,如根据用户的输入值指定数组的大小,印象中以前是不可以的.现在在gcc中是可以的(PS:ansi c标准是C90标准): ==== ...

  2. 获得easyUi dialog 对话框title的属性值

    <div id="dlg" class="easyui-dialog" title="Toolbar and Buttons" sty ...

  3. 利用C#轻松创建不规则窗体

    1.准备一个不规则的位图 可以使用任意一种你喜欢的作图工具,制作一个有形状的位图,背景使用一种其他的颜色.这个颜色在编程中用得着,所以最好使用一种容易记忆的颜色.如黄色,文件名为bk.bmp 2.创建 ...

  4. HTML5新属性-----拖放

    最早引入JS拖放功能的是IE4,当时,网页中只有两种对象可以拖放:图像和某些文本.拖动图像时,把鼠标放在图像上,按住鼠标不放就可以拖动它.拖动文本时,需要选中文本,然后可以像拖动图像一样拖动被选中的文 ...

  5. Oracle EBS-SQL (PO-2):检查当月到货补单的记录数.sql

    SELECT          DECODE(PLLA.FROM_LINE_ID,'-1','手工','','自动创建') 下达方式,          rsh.receipt_num         ...

  6. Delphi之TDrawGrid绘制

    一直都对QQ的好友列表很好奇,最先感觉用TreeView实现的,看了看TreeView的源码,发现要实现还真的不太好完成任务啊,其中最大的原因是自己的功力不足,后来觉得用ListView来做吧,结果也 ...

  7. java.lang.OutOfMemoryError: PermGen space 解决方案

    只需两步: 将值改为512或者1024,然后CTRL+S,重启tomcat 和eclipse即可.

  8. js计算时间差,包括计算,天,时,分,秒

    收集两个计算时间差的计算方法代码片段: var date1=new Date(); //开始时间 var date2=new Date(); //结束时间 var date3=date2.getTim ...

  9. 复习day12-23

    获取请求中的内容: request.getParameter(); get方式因为在地址栏所以需要转码: String name = new String(req.getparameter().get ...

  10. mac隐藏或显示文件

    1,显示方法:在“终端” 输入命令 defaults write com.apple.finder AppleShowAllFiles TRUE killall Finder 重启Finder,系统隐 ...