• 泛型枚举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();
            }
        }

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

  • 相关阅读:
    基于CORTEX-M的实时嵌入式系统
    FileZilla 安装配置参考
    【转】Difference between Point-To-Point and Publish/Subscribe JMS Messaging Models
    flush();close();dispose()
    work staff
    堆、栈、内存管理
    2013.8.1 读程序笔记
    C# static
    只包含schema的dll生成和引用方法
    4个月记
  • 原文地址:https://www.cnblogs.com/aaronguo/p/2626992.html
Copyright © 2020-2023  润新知