C# foreach 今生

1.编写自己的迭代器,和FCL迭代模式是对应.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EnumerableDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //使用接口IMyEnumerable 代替MyList
            IMyenumerable list = new MyList();
            //得到迭代器,在循环中针对迭代器编码,而不是集合MyList
            IMyEnumerator enumerator = list.GetEnumberator();

            //方式一:
            for (int i = 0; i < list.Count; i++)
            {
                object current = enumerator.Current;
                enumerator.MoveNext();
            }

            //方式二:
            while (enumerator.MoveNext())
            {
                object current = enumerator.Current;
            }
        }
    }

    /// <summary>
    /// 要求所有的迭代器全部实现该接口
    /// </summary>
    interface IMyEnumerator
    {
        bool MoveNext();
        object Current { get; }
    }


    /// <summary>
    /// 要求所有的集合实现该接口
    /// 客户端就可以针对该接口编码
    /// 而无需关注具体的实现
    /// </summary>
    interface IMyenumerable
    {
        IMyEnumerator GetEnumberator();
        int Count { get; }
    }

    class MyList : IMyenumerable
    {

        object[] items = new object[10];
        IMyEnumerator myEnumerator;

        public object this[int i]
        {
            get { return items[i]; }
            set { this.items[i] = value; }
        }

        public int Count
        {
            get
            {
                return items.Length;
            }
        }

        public IMyEnumerator GetEnumberator()
        {
            if(myEnumerator == null)
            {
                myEnumerator = new MyEnumerator(this);
            }
            return myEnumerator;
        }
    }

    class MyEnumerator : IMyEnumerator
    {
        int index = 0;
        MyList myList;

        public MyEnumerator(MyList myList)
        {
            this.myList = myList;
        }

        public object Current
        {
            get
            {
              return  myList[index - 1];
            }
        }

        public bool MoveNext()
        {
            if (index + 1 > myList.Count)
            {
                index = 1;
                return false;
            }
            else
            {
                index++;
                return true;
            }
        }
    }
}

2.无论是for循环还是while循环,都是不简洁的.于是foreach就诞生了.它用于遍历继承了IEnumerable或IEnumerable<T>接口的集合元素.

foreach(var x in xx){}

foreach循环除了可以提供简化的语法外,还有两个优势:

-1自动将代码置入try-finally块.

-2若类型实现了IDispose接口,它会在循环结束后自动调用Dispose方法.

反编译可以看到内部是:

using(List<object>.Enumerator CS$5$0000 =list.GetEnumerator())

{

  while(CS$5$000.MoveNext())

  {

    object current = CS$5$0000.Current;

  }

}

 

posted @ 2015-01-16 21:16  拉斐  阅读(127)  评论(0)    收藏  举报