C# foreach或许你所不知道的

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值