Foreach 遍历原理

1:首先熟知的HashTable,List,ArrayList,dictionary等集合数组都可以通过Foreach来遍历实现,然后对象是不可以的,这是为什么?

 通过观察得知:HashTable,List,ArrayList,dictionary内部都实现了一个叫做IEnumerable的接口,这个接口里有一个方法叫做GetEnumerator可用于循环访问集合的 System.Collections.IEnumerator 对象;

那么可想而知:如果想要遍历一个对象中的数组,是否实现了IEnumerable接口就可以了呢?下面来一一推断

首先定义一个类:person

 public class Person
    {
        string[] str = { "Albin", "Mr.Zhang", "Mr.Shi" };
        private int _id;
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        private string _sex;
        public string Sex
        {
            get { return _sex; }
            set { _sex = value; }
        } 
    }

然后声明一个对象:

person per=new person();

foreach这里会提示错误信息为:person不包含GetEnumerator公共的定义,因此foreach不用作用与person类型的变量
foreach(string i in per)
{
console.writeline(
}
console.readkey();
-->foreach这里会提示错误信息为:person不包含GetEnumerator公共的定义,因此foreach不用作用与person类型的变量
所以我们就让person类来包含GetEnumerator这个方法,Getenumerator这个方法是在IEnumerable这个接口中,所以我们就要的person来实现这个接口就///可以了:
如下:

 public class Person  :IEnumerable
    {
        string[] str = { "liu", "zhang", "shi" };
        private int _id;
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        private string _sex;
        public string Sex
        {
            get { return _sex; }
            set { _sex = value; }
        }
        public IEnumerator GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }

这样看来我们的person类就有了Getenumerator这个方法,从而错误提示也消失了.Ok下面就注意了,Getenumerator它这个方法的类型是IEnumerator类型的,那么我是就必须要定义个IEnumerator类型的类来实现GetEnumerator这个方法

如下:下面这个代码才是真正的内部循环


1:先来了解下面的字面意思
2:我们要循环的是对象数组所以我们要将要循环的数组传到这个personenum类中,(通过构造函数)
3:循环它是一个过程,会从第一个开始然后到最后一个结束,一一的将数组的每一条数组打印出来,那么在MoveNext的意思就是根据下标来循环数组中的每一条,然后一一的向下进行,知道循环到最后一条数组唯一,所以我们要定义一个下标int Index=-1 赋值为-1 意思是说,在进行循环的时候,它会从第一条开始,也就是我们的下标0,在MoveNext方法中,Index++.表示Index=1,所以我们为Index的初始值赋值为-1;
4:那么Current表示的是当前的对象:通过MoveNext我们知道,这个方法返回的是通过下标访问的每一条数组所以就是 return _per[index];
5:最后的Reset()这个方法是重置的意思,意思就是所没当我们调用一次Foreach 我们都会从第一条数据开始,所以要将我们的下标重置为-1;

 public class personenum : IEnumerator
    {
        public personenum(string[] per)
        {
            this._per = per;
        }
        private string[] _per;
        public object Current    ---------->当前的对象
        {
            get { return _per[index]; }
        }
        int index = -1;
        public bool MoveNext()   --------------移除下一个
        {
            index++;
            if (index >= _per.Length)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        public void Reset()         ------------重置
        {
            index = -1;
        }
    }

Ok!整个的Foreach循环的内部原理就是这个了.

下面还有一个更好玩的东西,既然是实现了Getenumerator这个方法那么我们不使用foreach循环直接调用这个方法是不是也可以呢??答案是肯定的,代码奉上

IEnumerator ienum = per.GetEnumerator();
while (ienum.MoveNext())
{
Console.WriteLine(ienum.Current);
}
Console.ReadKey();

原理是一个样..

posted @ 2013-11-29 00:21  Mr.liub  阅读(613)  评论(0)    收藏  举报