迭代器

迭代器模式的原始图如下:

事例代码:

    class Program
    {
        static void Main(string[] args)
        {
            ConAggregate<string> ca = new ConAggregate<string>();
            ca.Datas = new string[] { "sdf","wefwe","efwfw","swsdfw"};

            foreach (var  test in ca.Datas)
            {
                Console.WriteLine(test);
            }
        }
    }

    public abstract class Aggegate<T>
    {
        public abstract ITerator<T> GeTerator();
    }

    public class ConAggregate<T> : Aggegate<T>
    {
        public T[] Datas { set; get; }

        public override ITerator<T> GeTerator()
        {
            return new ConIterator<T>(this);
        }
    }

    public interface ITerator<out T>
    {
        void Reset();
        bool MoveNext();

        T CurrentItem { get; }
    }

    public class ConIterator<T> : ITerator<T>
    {
        private ConAggregate<T> ct;

        int position = -1;
        public ConIterator(ConAggregate<T> c)
        {
            ct = c;
        }

        public T CurrentItem
        {
            get { return ct.Datas[position]; }
        }

        public void Reset()
        {
            position = -1;
        }

        public bool MoveNext()
        {
            position++;
            return position < ct.Datas.Length;
        }
    }

 

 

 c# 有IEnumerable,IEnumerator 两个接口 实现这两个接口 既可完成迭代。即可以使用Foreach 做遍历。 引用MSDN里容器代码

    class Program
    {
        static void Main(string[] args)
        {
            BoxCollection bxList = new BoxCollection();
            bxList.Add(new Box(10, 4, 6));
            bxList.Add(new Box(4, 6, 10));
            bxList.Add(new Box(6, 10, 4));
            bxList.Add(new Box(12, 8, 10));
            bxList.Add(new Box(10, 4, 6));

            foreach (Box bx in bxList)
            {
                Console.WriteLine("{0}\t{1}\t{2}\t{3}",
                    bx.Height.ToString(), bx.Length.ToString(),
                    bx.Width.ToString(), bx.GetHashCode().ToString());
            }
        }
    }

    public class Box 
    {
        public Box(int h, int l, int w)
        {
            this.Height = h;
            this.Length = l;
            this.Width = w;
        }
        public int Height { get; set; }
        public int Length { get; set; }
        public int Width { get; set; }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
    public class BoxCollection : IEnumerable<Box>
    {
        // The generic enumerator obtained from IEnumerator<Box>
        // by GetEnumerator can also be used with the non-generic IEnumerator.
        // To avoid a naming conflict, the non-generic IEnumerable method
        // is explicitly implemented.

        public IEnumerator<Box> GetEnumerator()
        {
            return new BoxEnumerator(this);
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return new BoxEnumerator(this);
        }

        // The inner collection to store objects.
        private List<Box> innerCol;

        public BoxCollection()
        {
            innerCol = new List<Box>();
        }

        // Adds an index to the collection.
        public Box this[int index]
        {
            get { return (Box)innerCol[index]; }
            set { innerCol[index] = value; }
        }

        // Determines if an item is in the collection
        // by using the BoxSameDimensions equality comparer.
        public bool Contains(Box item)
        {
            bool found = false;

            foreach (Box bx in innerCol)
            {
                // Equality defined by the Box
                // class's implmentation of IEquitable<T>.
                if (bx.Equals(item))
                {
                    found = true;
                }
            }
            return found;
        }

        public bool Contains(Box item, EqualityComparer<Box> comp)
        {
            bool found = false;

            foreach (Box bx in innerCol)
            {
                if (comp.Equals(bx, item))
                {
                    found = true;
                }
            }
            return found;
        }
        public void Add(Box item)
        {

            if (!Contains(item))
            {
                innerCol.Add(item);
            }
            else
            {
                Console.WriteLine("A box with {0}x{1}x{2} dimensions was already added to the collection.",
                    item.Height.ToString(), item.Length.ToString(), item.Width.ToString());
            }
        }

        public void Clear()
        {
            innerCol.Clear();
        }
        public void CopyTo(Box[] array, int arrayIndex)
        {
            if (array == null)
                throw new ArgumentNullException("The array cannot be null.");
            if (arrayIndex < 0)
                throw new ArgumentOutOfRangeException("The starting array index cannot be negative.");
            if (Count > array.Length - arrayIndex + 1)
                throw new ArgumentException("The destination array has fewer elements than the collection.");

            for (int i = 0; i < innerCol.Count; i++)
            {
                array[i + arrayIndex] = innerCol[i];
            }
        }
        public int Count
        {
            get
            {
                return innerCol.Count;
            }
        }
        public bool IsReadOnly
        {
            get { return false; }
        }
       
    }

    public class BoxEnumerator : IEnumerator<Box>
    {
        private BoxCollection _collection;
        private int curIndex;
        private Box curBox;


        public BoxEnumerator(BoxCollection collection)
        {
            _collection = collection;
            curIndex = -1;
            curBox = default(Box);
        }

        public bool MoveNext()
        {
            //Avoids going beyond the end of the collection.
            if (++curIndex >= _collection.Count)
            {
                return false;
            }
            else
            {
                // Set current box to next item in collection.
                curBox = _collection[curIndex];
            }
            return true;
        }

        public void Reset() { curIndex = -1; }

        void IDisposable.Dispose() { }

        public Box Current
        {
            get { return curBox; }
        }


        object IEnumerator.Current
        {
            get { return Current; }
        }

    }

 

 

 使用yield return

       msdn 对yield的说明:在语句中使用 yield 关键字,表示在该关键字所在的方法、运算符或 get 访问器是迭代器。 通过使用 yield 定义迭代器,可在实现自定义集合类型的 IEnumerable 和 IEnumerator 模式时无需其他显式类。

public class BoxCollection 
    {
        public IEnumerator<Box> GetEnumerator()
        {
            foreach (var i in innerCol)
            {
                yield return i;
            }
         }// The inner collection to store objects.
        private List<Box> innerCol;

        public BoxCollection()
        {
            innerCol = new List<Box>();
        }

        // Adds an index to the collection.
        public Box this[int index]
        {
            get { return (Box)innerCol[index]; }
            set { innerCol[index] = value; }
        }

        // Determines if an item is in the collection
        // by using the BoxSameDimensions equality comparer.
        public bool Contains(Box item)
        {
            bool found = false;

            foreach (Box bx in innerCol)
            {
                // Equality defined by the Box
                // class's implmentation of IEquitable<T>.
                if (bx.Equals(item))
                {
                    found = true;
                }
            }
            return found;
        }

        public bool Contains(Box item, EqualityComparer<Box> comp)
        {
            bool found = false;

            foreach (Box bx in innerCol)
            {
                if (comp.Equals(bx, item))
                {
                    found = true;
                }
            }
            return found;
        }
        public void Add(Box item)
        {

            if (!Contains(item))
            {
                innerCol.Add(item);
            }
            else
            {
                Console.WriteLine("A box with {0}x{1}x{2} dimensions was already added to the collection.",
                    item.Height.ToString(), item.Length.ToString(), item.Width.ToString());
            }
        }

        public void Clear()
        {
            innerCol.Clear();
        }
        public void CopyTo(Box[] array, int arrayIndex)
        {
            if (array == null)
                throw new ArgumentNullException("The array cannot be null.");
            if (arrayIndex < 0)
                throw new ArgumentOutOfRangeException("The starting array index cannot be negative.");
            if (Count > array.Length - arrayIndex + 1)
                throw new ArgumentException("The destination array has fewer elements than the collection.");

            for (int i = 0; i < innerCol.Count; i++)
            {
                array[i + arrayIndex] = innerCol[i];
            }
        }
        public int Count
        {
            get
            {
                return innerCol.Count;
            }
        }
        public bool IsReadOnly
        {
            get { return false; }
        }
       
    }

 

 

 

 

 

 

                

posted @ 2016-03-14 15:26  坚硬的鸡蛋  阅读(124)  评论(0)    收藏  举报