随心所欲~我也做个集合遍历器吧(自己的foreach,委托人威力)_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 随心所欲~我也做个集合遍历器吧(自己的foreach,委托人威力)

随心所欲~我也做个集合遍历器吧(自己的foreach,委托人威力)

 2013/9/3 18:19:38  张占岭  博客园  我要评论(0)
  • 摘要:感觉微软在面向对象三大原则中,封装性运用的最为突出,它会将一些复杂的算法,结构,功能代码进行封装,让程序员在使用时十分得心应手,如关键字里的foreach和labmda表达式里的Foreach等等,今天我也来写一个集合遍历器得了,呵呵。小知识:你的集合如果是List,那么它里面的N多方法都是可以拿来就用的,今天的遍历功能,使用List里的GetEnumerator()方法实现,它返回的其实是一个Enumerator结果体,这个枚举器的结构体如下
  • 标签:for 遍历 随心 自己

感觉微软在面向对象三大原则中,封装性运用的最为突出,它会将一些复杂的算法,结构,功能代码进行封装,让程序员在使用时十分得心应手,如关键字里的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> { "1", "2", "3", "4", "5" };
            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);
            });

通过这篇文章,我们可以完全领略到委托的威力,呵呵。

发表评论
用户名: 匿名