foreach

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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方法获得元素。

 

以上是关于foreach的主要内容,如果未能解决你的问题,请参考以下文章

C#VS快捷键

C#VS快捷键

实用代码片段

方便调试使用的代码片段

vue2.0 代码功能片段

sublime 添加代码片段(snippets)