昨天看了一下foreach实现原理(通过创建枚举器),今天将知识汇总下方便以后回头看看,同时希望可以帮到更多的人。
废话不多说,上正式解释。
其实通过foreach遍历数据,实际上是调用了一个“枚举器”来遍历数据,和foreach一点关系都没有,而foreach只是语法上的一个简化而已。写foreach只是降低枚举的复杂度,使程序员不用自己写复杂的遍历逻辑,只用调用foreach即可实现。
但是想我们这样不平凡的人,怎么甘愿总用着foreach却不懂其原理呢! 哈哈
上代码:
namespace FanXing
{
// 需要让该类型实现一个叫IEnumerable的接口,并重写GetEnumerator方法(注意重写完此方法后,接口可删除。其实需要的不是这个接口而是这个方法)
class ForeachFX : IEnumerable
{
string[] m_love = new string[] { "理智", "林青霞", "李若彤", "刘亦菲" };
// 这个方法的作用是获取一个枚举器
public IEnumerator GetEnumerator()
{
return new ForeachEnumerator(this.m_love); // return一个ForeachEnumerator对象//throw new NotImplementedException();
}
}
// 这个类型就是一个枚举器
class ForeachEnumerator : IEnumerator
{
string[] m_love = null;
int index = -1; // 根据索引下标遍历数组,注意:下标一般都起到开始的前一个
public ForeachEnumerator(string[] m_love)
{
this.m_love = m_love;
}
public object Current // 当前值。如其所是为object类型
{
get
{
if(index >= 0 && index < m_love.Length)
{
return m_love[index];
}else
{
throw new IndexOutOfRangeException();
}
}
}
public bool MoveNext() // 获取下一个
{
if(index + 1 < m_love.Length)
{
index++;
return true;
}
return false;
//throw new NotImplementedException();
}
public void Reset() // 将index重置为-1
{
index = -1;
}
}
}
main 函数代码:
ForeachFX foreachfx = new ForeachFX();
// 调用GetEnumerator方法,返回ForeachEnumerator对象传给IEnumerator
IEnumerator ienumerator = foreachfx.GetEnumerator();
while (ienumerator.MoveNext()) // 调用MoveNext()方法,进行下一个
{
// 输出Current
Console.WriteLine(ienumerator.Current.ToString());
}
// 重置,将index重置为-1
ienumerator.Reset();
Console.ReadKey();
如以上所示,就创建一个枚举器,通过以上枚举器就可以实现foreach的遍历。而两个类分别继承的IEnumerable、IEnumerator接口,皆可删除。接口中重写的方法才是我们写上接口的目的。