黑马程序员技术交流社区

标题: C#要使一个类支持foreach遍历,实现过程是怎样的? [打印本页]

作者: 王起    时间: 2013-3-14 12:54
标题: C#要使一个类支持foreach遍历,实现过程是怎样的?
本帖最后由 王起 于 2013-3-15 13:03 编辑

如题,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;

这样遍历

作者: 石国庆    时间: 2013-3-14 15:25
foreach 语句为数组或对象集合中的每个元素重复一个嵌入语句组。foreach 语句用于循环访问集合以获取所需信息,但不应用于更改集合内容以避免产生不可预知的副作用。此语句的形式如下:
foreach (type identifier in expression) statement
其中:
type
identifier 的类型。
identifier
表示集合元素的迭代变量。如果迭代变量为值类型,则无法修改的只读变量也是有效的。
expression
对象集合或数组表达式。集合元素的类型必须可以转换为 identifier 类型。请不要使用计算为 null 的表达式。
而应计算为实现 IEnumerable 的类型或声明 GetEnumerator 方法的类型。在后一种情况中,GetEnumerator 应该要么返回实现 IEnumerator 的类型,要么声明 IEnumerator 中定义的所有方法。
statement
要执行的嵌入语句。
事例:
int[] arr = new int[] { 0, 1, 2, 3, 4 };
foreach (int i in arr)
{
Console.Write(i);
}
作者: 曾玉锋    时间: 2013-3-14 16:19
本帖最后由 曾玉锋 于 2013-3-14 16:29 编辑

以下两个示例是我参照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属性取得当前对象进行操作

这都是我自己的理解,如果有错误的地方,请指正,谢谢!


作者: 王起    时间: 2013-3-15 13:03
谢谢大家!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2