穷举是找出所有符合某一个条件的对象的集合,例如全部对象有100个,分别是从1到100,条件是找出小于50的对象,穷举就是分别拿这100个对象与50对比来判断这个对象是否符合条件,将符合条件的对象放在一起构成一个集合。
(这里为方便理解,举了一个很简单的例子,而实际上的穷举的全部对象可能是数万个,甚至无穷的)
枚举是对一个已经存在的集合进行举例,找出集合中的每一个对象。要注意的是,也许我们刚开始不知道集合中有多少个对象,但当我们开始枚举之前是知道的。
迭代是按照顺序的方式,一般是从前到后依次的顺序枚举集合。
当然我们也可以按照从后到前的方式枚举集合。
甚至也可以间隔一个的方式枚举集合等等。
枚举的方式有很多,但从代码实现的角度来看,迭代的方式是其他方式实现的基础。
对集合枚举是非常普遍的,因此,需要将枚举分离出来,封装变化。
public interface IEnumerable//定义了一个可枚举接口,如果某个类继承这个接口,表示这个类的实例对象是可枚举的。
{
IEnumerator GetEnumerator();//接口中定义了一个获取枚举器(迭代器)
}
public interface IEnumerable : IEnumerable //泛型可枚举接口
{
new IEnumerator GetEnumerator();//new关键字表示隐藏IEnumerable中定义的方法
}
注意:尽管Enumerator是枚举器的意思,但我们在这里将其视为迭代器,意为采用迭代方式枚举的枚举器
public interface IEnumerator
{
bool MoveNext();//移动到下一个元素,移动成功返回True,否则返回false,false表示当前元素是最后一个元素
Object Current//当前元素
{
get;
}
void Reset();//重置,回到初始状态
}
public interface IEnumerator : IDisposable, IEnumerator
{
new T Current
{
get;
}
}
public abstract class Array : ICloneable, IList, IStructuralComparable, IStructuralEquatable
{//IList继承了IEnumerable
public IEnumerator GetEnumerator()
{
int lowerBound = GetLowerBound(0);
if (Rank == 1 && lowerBound == 0)
return new SZArrayEnumerator(this);
else
return new ArrayEnumerator(this, lowerBound, Length);//返回迭代器,可以有多个迭代器
}
}
[Serializable]
private sealed class ArrayEnumerator : IEnumerator, ICloneable//定义一个Array的迭代器,继承自IEnumerator
{
private Array array;
private int index;
private int endIndex;
private int startIndex; // Save for Reset.
private int[] _indices; // The current position in a multidim array
private bool _complete;
internal ArrayEnumerator(Array array, int index, int count)
{
this.array = array;
this.index = index - 1;
startIndex = index;
endIndex = index + count;
_indices = new int[array.Rank];
int checkForZero = 1; // Check for dimensions of size 0.
for (int i = 0; i < array.Rank; i++)
{
_indices[i] = array.GetLowerBound(i);
checkForZero *= array.GetLength(i);
}
// To make MoveNext simpler, decrement least significant index.
_indices[_indices.Length - 1]--;
_complete = (checkForZero == 0);
}
private void IncArray()
{
int rank = array.Rank;
_indices[rank - 1]++;
for (int dim = rank - 1; dim >= 0; dim--)
{
if (_indices[dim] > array.GetUpperBound(dim))
{
if (dim == 0)
{
_complete = true;
break;
}
for (int j = dim; j < rank; j++)
_indices[j] = array.GetLowerBound(j);
_indices[dim - 1]++;
}
}
}
public Object Clone()
{
return MemberwiseClone();
}
public bool MoveNext()
{
if (_complete)
{
index = endIndex;
return false;
}
index++;
IncArray();
return !_complete;
}
public Object Current
{
get
{
if (index < startIndex) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
if (_complete) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
return array.GetValue(_indices);
}
}
public void Reset()
{
index = startIndex - 1;
int checkForZero = 1;
for (int i = 0; i < array.Rank; i++)
{
_indices[i] = array.GetLowerBound(i);
checkForZero *= array.GetLength(i);
}
_complete = (checkForZero == 0);
// To make MoveNext simpler, decrement least significant index.
_indices[_indices.Length - 1]--;
}
}
using System;
using System.Collections;
namespace MyLearn
{
class Program
{
static void Main(string[] args)
{
Array array = new Array();
foreach (object o in array)//可以使用foreach直接获取_indic的元素
{
Console.WriteLine(o);
}
Console.ReadKey();
}
}
public class Array : IEnumerable
{
private int[] _indic = {5,3,5,6,7,2};
public IEnumerator GetEnumerator()
{
return ArrayEnumerator();
}
public IEnumerator ArrayEnumerator()
{
for (int i = 0; i < _indic.Length; i++)
{
yield return _indic[i];//对Aarry中的_indic进行枚举
}
}
}
}