如题,C#要使一个类支持foreach遍历,实现过程是怎样的?作者: 边亮 时间: 2013-3-14 13:16
首先建立一个类的数组;
然后
class person
{
public string name
{
get;
srt;
}
}
person p1=new person(){name="张三"};
person p2=new person(){name="李四"};
person p3=new person(){name="王五"};
person[] per={p1,p2,p3}; //定义一个person数组
foreach(person itrm in per)
{
console.write(item.name);//遍历调用这个数组中对象的属性
console.srite(item);
}
console.readkey;
以下两个示例是我参照List<T>和ArrayList写的,其中一些方法的代码是我猜的,不知道是否正确,但运行还算正常
示例一:
//自定义集合,可以存储object类型数据
public class MyArray : IEnumerable,IEnumerator
{
//用于存储数据
ArrayList list = new ArrayList();
//用于记录指针或者游标位置
int index = -1;
//添加元素
public void Add(object item)
{
list.Add(item);
}
//得到IEnumerator
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
//得到当前对象
public object Current
{
get { return list[index]; }
}
//游标往后移动一位,如果没有超出list长度,则可以继续遍历,否则遍历结束
public bool MoveNext()
{
index++;
return index > list.Count - 1 ? false : true;
}
//将游标重置
public void Reset()
{
index = -1;
}
}
示例二
//自定义泛型集合
public class MyList<T> : IEnumerable<T>, IEnumerator<T>,IDisposable
{
//创建一个List<T>集合存储对象
private List<T> list = new List<T>();
int index = -1;
//添加对象
public void Add(T item)
{
list.Add(item);
}
//因为foreach需要迭代器IEnumerator类型,所以,把当前对象根据里氏转换原则,转换为其父类型
public IEnumerator<T> GetEnumerator()
{
return (IEnumerator<T>)this;
}
//这里也不清楚 是干嘛的!!!
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
//获得当前对象
public T Current
{
get {
return list[index];
}
}
//这个是释放对象吧,
public void Dispose()
{
//这里不清楚怎样释放对象资源,我觉得把里面的资源给设为null,然后调用垃圾回收器回收
//应该没啥问题了,还好了,这里看自己怎么写合适
this.list = null;
GC.Collect();
}
//...这个没弄明白 ????代码是我自己加的
object System.Collections.IEnumerator.Current
{
get { return Current; }
}
//根据游标的位置判断是否已经遍历完所有元素,如果没有遍历完,则可以继续遍历
public bool MoveNext()
{
index++;
return index > list.Count-1? false : true;
}
//将游标重置
public void Reset()
{
index = -1;
}
}
foreach 迭代过程:
1.先用当前对象(集合)的GetEnumerator取得一个IEnumerator对象并存储到内存空间
2.然后通过调用MoveNext()方法,通过游标位置,判断是否已经遍历完了,如果没有则返回true;
3.根据MoveNext()得到的结果,如果还有元素没有遍历,则通过Current属性取得当前对象进行操作