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();
原理是一个样..

浙公网安备 33010602011771号