ForEach 的使用

来源:互联网 发布:java log4j 日志级别 编辑:程序博客网 时间:2024/05/22 10:59

ForEach 是一个循环结构,但是却不像 for 一样使用下标。

它用于 数组 和 集合 的遍历。

1、数组的遍历

int[] arr = new int[]{1, 2, 3, 4};foreach(int element in arr){     Console.WriteLine(element);}

2、集合的遍历

using System.Collections;...ArrayList list = new ArrayList();list.Add("hello");list.Add("guys");foreach(string e in list){     Console.WriteLine(e);}

3、泛型集合的遍历

using System.Collections.Generic;...List<int> list = new List<int>();list.Add(1);list.Add(3);list.Add(5);foreach(int e in list){     Console.WriteLine(e);}

 

注意:虽然,ForEach 和 For 一样都是循环结构,但是,它们之间比较大的区别就在于,在Foreach内部是不能对 元素进行修改的,否则会发生编译错误。

ForEach中的变量是ReadOnly变量。

foreach(int e in list){     if(e == 3)     {           e = 6; //导致编译错误,不能修改,因为是 只读  变量      }}


如果,想要对遍历 数组或集合中的数据进行修改的话,就 改用 for 循环吧!

 

有时,我们不仅希望能够在 数组 和集合中使用 Foreach 循环,我们还希望对我们自定义的类使用ForEach循环。

什么意思呢?就是,对自定义的类的使用 Foreach循环,获取内部的元素。

 

这时,对于自定义的类,需要去继承 IEnumerable 或者 IEnumerable<T> 接口,就可以了。

IEnumetable 接口中 只有一个方法IEnumerator GetEnumerator()

由于返回值为 IEnumerator 意味着,我们还需要去 定义一个类 继承IEnumerator 接口。

IEnumerator 是所有非泛型枚举数的基接口。枚举数可用于读取集合中的数据,但不能用于修改基础集合

在IEnumerator中,有三个东西 需要我们去实现,分别是 bool MoveNext(), void Reset(), object Current.

 

public class Person    {        string name;        int age;        public Person(string name, int age)        {            this.name = name;            this.age = age;        }        public override string ToString()        {            return this.name + " " + this.age;        }    }    public class People : IEnumerable    {        private Person[] people;        public People(Person[] _people)        {            people = new Person[_people.Length];            for (int i = 0; i < _people.Length; i++)            {                people[i] = _people[i];            }        }        public IEnumerator GetEnumerator()        {            return (IEnumerator)new PeopleEnumerator(this);        }        public class PeopleEnumerator : IEnumerator        {            private People p;            private int position = -1;            public PeopleEnumerator(People p)            {                this.p = p;            }            public bool MoveNext()            {                if (position < p.people.Length - 1)                {                    position++;                    return true;                }                else                 {                    return false;                }            }            public void Reset()            {                position = -1;            }            public object Current            {                get { return this.p.people[position]; }            }        }        static void Main()        {            Person[] Persons = new Person[] { new Person("kim", 20), new Person("tim", 23) };            People p = new People(Persons);            foreach (object obj in p) {                Person o = (Person)obj;                Console.WriteLine(o);            }            Console.ReadKey(true);        }    }

 

其实,我们不用实现 IEnumerable 接口也能够使用 Foreach循环。只要在 类中有 GetEnumerator()方法和一个具有

MoveNext()、Reset()、Current 这三个东西的类,同样能够能行!

代码示例:

public class Person    {        string name;        int age;        public Person(string name, int age)        {            this.name = name;            this.age = age;        }        public override string ToString()        {            return this.name + " " + this.age;        }    }    public class People    {        private Person[] people;        public People(Person[] _people)        {            people = new Person[_people.Length];            for (int i = 0; i < _people.Length; i++)            {                people[i] = _people[i];            }        }        public PeopleEnumerator GetEnumerator()        {            return new PeopleEnumerator(this);        }        public class PeopleEnumerator        {            private People p;            private int position = -1;            public PeopleEnumerator(People p)            {                this.p = p;            }            public bool MoveNext()            {                if (position < p.people.Length - 1)                {                    position++;                    return true;                }                else                 {                    return false;                }            }            public void Reset()            {                position = -1;            }            public Person Current            {                get { return this.p.people[position]; }            }        }        static void Main()        {            Person[] Persons = new Person[] { new Person("kim", 20), new Person("tim", 23) };            People p = new People(Persons);            foreach (Person mate in p){                Console.WriteLine(mate);            }            Console.ReadKey(true);        }    }

上例中,没有再继承 IEnumerable 接口,但是得到了相同的结果。但是书上说,这个还能够改进,两者同时使用。

但是,我不太懂它的含义就,暂且搁置!


原创粉丝点击