zoukankan      html  css  js  c++  java
  • 泛型枚举IEnumerable<T>与泛型迭代IEnumerator<T>

    IEnumerable<T>接口在.NET中是非常重要的接口,它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简单的迭代,搭配使用的重要接口当然就是泛型迭代IEnumerator<T>,支持泛型集合上的简单迭代

    命名空间:

    using System.Collections.Generic;
    using System.Collections;

    一般的简单写法:

    View Code
    /// <summary>
        /// IEnumerable<T> -- 一般写法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class MyColl<T>:IEnumerable<T>
        {
            private T[] items;
    
            public MyColl(T[] item)
            {
                this.items = item;
            }
    
            public IEnumerator<T> GetEnumerator()
            {
                return new NestedEnumerator(this);
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
    
            class NestedEnumerator:IEnumerator<T> 
            {
                private MyColl<T> coll;
                private T current;
                private int index; //索引
    
                public NestedEnumerator(MyColl<T> coll)
                {
                    Monitor.Enter(coll.items.SyncRoot);
                    this.index = -1;
                    this.coll = coll;
                }
    
                public T Current
                {
                    get { return current; }
                }
    
                public void Dispose()
                {
                    try
                    {
                        current = default(T);
                        index = coll.items.Length;
                    }
                    finally {
                        Monitor.Exit(coll.items.SyncRoot);
                    }
                }
    
                object IEnumerator.Current
                {
                    get { return Current; }
                }
    
                public bool MoveNext()
                {
                    if (++index >= coll.items.Length)
                    {
                        return false;
                    }
                    else
                    {
                        current = coll.items[index];
                        return true;
                    }
                }
    
                public void Reset()
                {
                    current = default(T);
                    index = 0;
                }
            }
        }

    IEnumerable<T>枚举器--捷径写法:

    View Code
    /// <summary>
        /// IEnumerable<T>枚举器--捷径写法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class MyCollCut<T> : IEnumerable<T>
        {
            private T[] item;
            public MyCollCut(T[] item)
            {
                this.item = item;
            }
    
            public IEnumerator<T> GetEnumerator()
            {
                return GetEnumerator(false);
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
    
            /// <summary>
            /// 接受bool型参数的GetEnumerator方法
            /// </summary>
            /// <param name="synchronized">指示调用者是否需要一个同步或非同步的枚举器</param>
            /// <returns></returns>
            public IEnumerator<T> GetEnumerator(bool synchronized)
            { 
                return( new EnumWrapper<T>(GetPrivateEnumerator(synchronized)));
            }
    
            private IEnumerator<T> GetPrivateEnumerator(bool synchronized)
            {
                if (synchronized)
                {
                    Monitor.Enter(item.SyncRoot);
                }
                try
                {
                    foreach (T i in item)
                    {
                        yield return i; //传入yield块方法中的参数,都被作为公共字段加入生成的枚举器类中
                    }
                }
                finally
                {
                    if (synchronized)
                    {
                        Monitor.Exit(item.SyncRoot);
                    }
                }
            }
        }

    接受bool型参数的GetEnumerator方法:

            /// <summary>
            /// 接受bool型参数的GetEnumerator方法
            /// </summary>
            /// <param name="synchronized">指示调用者是否需要一个同步或非同步的枚举器</param>
            /// <returns></returns>
            public IEnumerator<T> GetEnumerator(bool synchronized)
            { 
                return( new EnumWrapper<T>(GetPrivateEnumerator(synchronized)));
            }
    
            private IEnumerator<T> GetPrivateEnumerator(bool synchronized)
            {
                if (synchronized)
                {
                    Monitor.Enter(item.SyncRoot);
                }
                try
                {
                    foreach (T i in item)
                    {
                        yield return i; //传入yield块方法中的参数,都被作为公共字段加入生成的枚举器类中
                    }
                }
                finally
                {
                    if (synchronized)
                    {
                        Monitor.Exit(item.SyncRoot);
                    }
                }
            }

    如果在遍历过程中区修改这些公共字段,必定将枚举器搞的一团糟,因此我们通过引入额外的间接层来防止这个麻烦,EnumWrapper<T>包装器,将枚举器包含在EnumWrapper<T>包装器中并返回这个包装器.

    EnumWrapper<T>:

    View Code
    public class EnumWrapper<T> : IEnumerator<T>
        {
            private IEnumerator<T> inner;
    
            public EnumWrapper(IEnumerator<T> inner)
            {
                this.inner = inner;
            }
    
            public T Current
            {
                get { return inner.Current; }
            }
    
            public void Dispose()
            {
                inner.Dispose();
            }
    
            object IEnumerator.Current
            {
                get { return inner.Current; }
            }
    
            public bool MoveNext()
            {
                return inner.MoveNext();
            }
    
            public void Reset()
            {
                inner.Reset();
            }
        }

    泛型枚举与泛型迭代先到这了...如果有哪里不正确的地方还请大家指出.谢谢

  • 相关阅读:
    一起谈.NET技术,抛砖引玉:我看微软.NET各子技术领域之应用前景 狼人:
    一起谈.NET技术,Windows Mobile 6.5的开始菜单 狼人:
    一起谈.NET技术,ASP.NET MVC 验证方式(1) 狼人:
    一起谈.NET技术,强烈推荐体验VisualStudio2010 RC 狼人:
    【华安php入门系列】第1天php的执行方式、执行过程
    败者树Java实现
    Android INSTALL_FAILED_ACWF_INCOMPATIBLE
    《构建高质量的C#代码》,新书上市,欢迎交流!
    oracle中的左右连接
    VS2012 UPDATE 2 发布了离线包
  • 原文地址:https://www.cnblogs.com/aaronguo/p/2626992.html
Copyright © 2011-2022 走看看