IEnumerator,IEnumerable接口,yield关键字

it2022-05-05  156

foreach可以迭代一些.net本来就为我们做好的类型,比如int,string等等

但是如果想迭代自己的类,就必须自己来写了

首先就要先实现IEnumerator的几个方法,和IEnumerable的GetEnumerator()方法

 

代码 foreach (person p  in  persons){   console.writeline(p)}//会解析为IEnumerator enumerator  =  persons.GetEnumerator(); while (enumerator.MoveNext()){   Person p  =  (Person)enumerator.Current;   Console.WriteLine(p);}

 

 

也就是说,foreach循环会调用IEnumerator下的几个方法

他们分别是:public bool MoveNext(),public void Reset(), public object Current属性

顾名思义

 

代码    public   class  Person    {         public  Person( string  fName,  string  lName)        {             this .firstName  =  fName;             this .lastName  =  lName;        }         public   string  firstName;         public   string  lastName;    }     public   class  People : IEnumerable    {         private  Person[] _people;         public  People(Person[] pArray)        {             // _people=pArray?????????             _people  =   new  Person[pArray.Length];             for  ( int  i  =   0 ; i  <  pArray.Length; i ++ )            {                _people[i]  =  pArray[i];            }        }         ///   <summary>          ///  接口的实现,返回的是一个PeopleEnum的一个类对象         ///   </summary>          ///   <returns></returns>          public  IEnumerator GetEnumerator()        {             return   new  PeopleEnum(_people);        }    }     public   class  PeopleEnum : IEnumerator    {         public  Person[] _people;         //  Enumerators are positioned before the first element         //  until the first MoveNext() call.          int  position  =   - 1 ;         public  PeopleEnum(Person[] list)        {            _people  =  list;        }         public   bool  MoveNext()        {            position ++ ;             return  (position  <  _people.Length);        }         public   void  Reset()        {            position  =   - 1 ;        }         public   object  Current        {             get             {                 try                 {                     return  _people[position];                }                 catch  (IndexOutOfRangeException)                {                     throw   new  InvalidOperationException();                }            }        }    }     class  App    {         static   void  Main()        {            Person[] peopleArray  =   new  Person[ 3 ]            {                new  Person( " John " " Smith " ),                new  Person( " Jim " " Johnson " ),                new  Person( " Sue " " Rabon " ),            };            People peopleList  =   new  People(peopleArray);             foreach  (Person p  in  peopleList)            {                Console.WriteLine(p.firstName  +   "   "   +  p.lastName);            }            Console.Read();        }    }

 

总结: 迭代自定义的类,必须实现实现GetEnumerator()方法返回IEnumerator

IEnumerator提供了foreach使用的方法属性

 

 

 

C#2.0有了yield关键字,就不用每次都这样实现IEnumerator接口了 包含yield语句的方法必须返回IEnumerator或者IEnumerable接口   代码     public   class  person    {         private   string  _Name;         public   string  Name {  get set ; }          public  person( string  name)        {            Name  =  name;        }         public   override   string  ToString()        {             return   this .Name;        }    }     class  people    {         private  person[] _person;         public  people(person[] person)        {            _person  =  person;        }         public  IEnumerator GetEnumerator()        {             for  ( int  i  =   0 ; i  <  _person.Length; i ++ )            {                 yield   return  _person[i];            }        }         public  IEnumerable reverse()        {             for  ( int  i  =  _person.Length  -   1 ; i  >=   0 ; i -- )            {                 yield   return  _person[i];            }        }    }     class  Program    {         static   void  Main( string [] args)        {            person[] p  =   new  person[ 3 ]            {                new  person( " John " ),                new  person( " Jim " ),                new  person( " Sue " ),            };            people pp  =   new  people(p);             foreach  (person pe  in  pp)            {                Console.WriteLine(pe);            }             foreach  (person ppp  in  pp.reverse())            {                Console.WriteLine(ppp);            }            Console.Read();        }    }

 

 

我认为yield关键字帮助我们实现了IEnumerator的方法

也可以自己定义迭代的方式,比如以上代码就实现了逆向循环。

 

参考:C#红皮书

  

转载于:https://www.cnblogs.com/renjuwht/archive/2009/12/24/1631764.html


最新回复(0)