泛型枚举IEnumerable与泛型迭代IEnumerator

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();

        }

    }

 

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

 

 

你可能感兴趣的:(enum)