C# foreach或许你所不知道的

来源:互联网 发布:python 最大回撤 编辑:程序博客网 时间:2024/05/14 18:13
 

1. 不是必须要IEnumerable和IEnumerator

众所周知foreach中in后面的对象应该是继承IEnumerable,程序运行时本质是在调用IEnumerable的GetEnumerator函数来返回一个IEnumerator对象,foreach就是利用IEnumerator对象的Current,MoveNext和Reset成员来进行一段数据的枚举,但是这个不是必须,比如下面代码:

 

    class FakeIEnumerable

    {

        public FakeIEnumerator GetEnumerator()

        {

            return new FakeIEnumerator(new double[] { 1, 34.3, -43, Double.NaN, 0.0043});

        }

}

 

    class FakeIEnumerator

    {

        double[] strs;

        int curIdx = -1;

 

        public FakeIEnumerator(double[] data)

        {

            strs = data;

        }

 

        public double Current

        {

            get

            {

                if (curIdx < 0 || curIdx >= strs.Length)

                    throw new InvalidOperationException();

                return strs[curIdx];

            }

        }

 

        public bool MoveNext()

        {

            return ++curIdx < strs.Length;

        }

 

        public void Reset()

        {

            curIdx = -1;

        }

}

 

    class Program

    {

        static void Main()

        {

            foreach (var item in new FakeIEnumerable())

                Console.WriteLine("类型: {0}  值: {1}", item.GetType(), item.ToString());

 

        }

    }

 

上面的两个类FakeIEnumerable和FakeIEnumerator都没有继承IEnumerable和IEnumerator,但是拥有IEnumerable和IEnumerator同名的成员信息,代码编译通过并成功运行。

输出

类型: System.Double  值: 1

类型: System.Double  值: 34.3

类型: System.Double  值: -43

类型: System.Double  值: NaN

类型: System.Double  值: 0.0043

 

可为什么这样呢?可以参考这个问题下面的回答,讲的不能再好了:

http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/64f3dbe3-5a1a-4a70-904a-792e26376dad

 

 

 

2. 支持继承IDisposable的IEnumerator

继承IDisposable的迭代器在foreach结束后会被正确处理掉(调用Dispose方法),另外这个不仅针对真的迭代器(继承IEnumerator的类),连上面说到的那个伪迭代器类FakeIEnumerator都是同等对待的。

 

更改上面FakeIEnumerator类代码

    class FakeIEnumerator: IDisposable

    {

        void IDisposable.Dispose()

        {

            Console.WriteLine("调用Dispose");

        }

 

        /* 后面代码同上... */

    }

 

运行结果

类型: System.Double  值: 1

类型: System.Double  值: 34.3

类型: System.Double  值: -43

类型: System.Double  值: NaN

类型: System.Double  值: 0.0043

调用Dispose

 http://www.cnblogs.com/mgen/archive/2011/07/01/2095960.html