zoukankan      html  css  js  c++  java
  • foreach

    实现了IEnumerable的对象才能用foreach遍历。foreach只管GetEnumerator方法。

    GetEnumerator如果是实现的接口,就必须返回一个IEnumerator的引用。

    定义一个person类

        class Person
        {
            public static int i;
            string name;
            int age;
            char gender;
    
            public Person()
            {
                i++;
                name = "name" + i.ToString();
            }
    
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            public int Age { get; set; }
            public char Gender { get; set; }
    
        }

    这个类的集合实现IEnumerable接口,里面要有一个GetEnumerator()方法返回一个IEnumerator对象。

       class MyGetEnumerater : IEnumerator
        {
            int i;
            ArrayList ps;
    
            public MyGetEnumerater(ArrayList al)
            {
                ps = al;
            }
    
            //如果MoveNext返回true就调用返回当前数据
            public object Current
            {
                get
                {
                    //object o = ps[i];
                    //i++;
                    //return o;
                    return ps[i++];
                }
            }
    
            //循环的时候指针下移一位,并判断是否有数据。
            public bool MoveNext()
            {
                if (i > ps.Count - 1)
                {
                    return false;
                }
                return true;
            }
    
            //重置
            public void Reset()
            {
                i = 0;
            }
        }
    
    
        class PersonCollection : IEnumerable
        {
            ArrayList al = new ArrayList();
    
            /// <summary>
            /// 实现了IEnumerable后 返回一个 迭代器接口对象,但具体的接口子类由程序员自己定义
            /// 也体现了 面向接口编程 的特点,不关心具体实现,对扩展开放。
            /// </summary>
            /// <returns></returns>
            public IEnumerator GetEnumerator()
            {
                return new MyGetEnumerater(al);
            }
    
            public Person this[int index]
            {
                get { return (Person)al[index]; }
            }
    
            public void Add(Person p)
            {
                al.Add(p);
            }
    
            public void AddRange(ICollection ip)
            {
                al.AddRange(ip);
            }
    
            public void Clear()
            {
                al.Clear();
            }
    
            public void Insert(int index,Person value)
            {
                al.Insert(index, value);
            }
            public int IndexOf(Person p)
            {
                return al.IndexOf(p);
            }
    
            public void RemoveAt(int index)
            {
                al.RemoveAt(index);
            }
    
            public void Remove(Person p)
            {
                if (al.Contains(p))
                {
                    int index = al.IndexOf(p);
                    al.RemoveAt(index);//or RemoveAt(index);
                }
            }
    
        }

    PersonCollection pc = new PersonCollection();
    pc.Add(new Person());
    pc.Add(new Person());

    foreach (Person item in pc)
    {
    Console.WriteLine(item.Name);
    }

    foreach内部所做的事情

    IEnumerable eable=pc as IEnumerable;//获得可迭代接口

    IEnumerator etor=eable.GetEnumerator();//获得迭代器(封装了集合的数据)

    while(etor.MoveNext())//

    {

    Person p=etor.Current;//获得数据,并执行循环体代码。

    ...

    }

    在使用自定义集合foreach循环时,不一定非得实现接口,只要包含接口里的方法就可以了。

    CLR在编译foreach时,直接调用被循环的集合对象的GetEnumerator方法以获得迭代器对象,直接调用对象的MoveNext方法检查是否存在元素,然后调用get_Current方法获得元素。

  • 相关阅读:
    ZOJ 4097 Rescue the Princess
    最大值最小化 最小值最大化
    SD第九届省赛B题 Bullet
    Euler Circuit UVA
    bzoj 1878
    随笔
    BZOJ
    主席树模板
    AC自动机模板
    BZOJ
  • 原文地址:https://www.cnblogs.com/buzhidaojiaoshenme/p/6839246.html
Copyright © 2011-2022 走看看