This article mainly introduced the C # IEnumerable and IEnumerator Interface Knowledge, has the very good reference value, below follows the small compilation together to look down
Warm so know new, can for the teacher, have time to review the basic knowledge is necessary, and can deepen understanding and memory.
foreach is commonly used to iterate through the collection, traversing the container that implements the IEnumerable interface, IEnumerable and IEnumerator interfaces I sometimes get a little confused, as the official explanation, IEnumerable is the enumerator interface, IEnumerator is an iterator interface, from the literal meaning of the difference is not small, one after the analysis.
IEnumerable interface
public interface ienumerable{ IEnumerator GetEnumerator ();}
Classes that inherit the IEnumerable interface need to implement the exposed GetEnumerator () method and return a IEnumerator interface object, and it seems that the real thing is ienumerator,f12 look at IEnumerator and what the hell.
IEnumerator interface
Public interface ienumerator{ object current {get;} bool MoveNext (); void Reset ();}
The IEnumerator interface has three east, one property current, returns the elements in the present collection, the method MoveNext () moves to the next, the traversal is not all backwards, reset (), the literal meaning of reset, this easy to understand. Make a hypothesis: since the IEnumerable interface return is implemented by an IEnumerator interface iterator, can only inherit the IEnumerator iterator interface implement a custom container?
Define a phone class
public class Phone {public string ' name; public phone (string name} {This] . name = name; }}
Define an iterator named Myenumerator and reality it interface IEnumerator
public class myenumerator:ienumerator{phone[] p; int idx =-1, public myenumerator (phone[] t) { p = t;} public obj ECT Current { get { if (idx = =-1) return new IndexOutOfRangeException (); return P[IDX]; } } public bool MoveNext () { idx++; return p.length > idx; } public void Reset () { idx =-1;}}
Class Program {static void Main (string[] args) {Show ("-----------IEnumerator------------"); phone[] phones = new phone[] {new phone ("iphone 7s"), New phone ("iphone 6s"), New phone ("iphone 5s")}; Myenumerator enumerator = new Myenumerator (phones); while (enumerator. MoveNext ()) { Phone p = Enumerator. Current as Phone; Show (P.name); } Console.readkey (); } static void Show (String i) { Console.WriteLine (i);}}
The results show:
As expected, the real thing is the IEnumerator interface, you can iterate through a custom container, but the original intention is to use foreach to do loop access, traversal. Well, then you can only display the IEnumerable interface to do it. Change the phone Class A little bit:
public class Phone:ienumerable {public string name, public Phone (string name) {This . name = name; } phone[] P; Public Phone (phone[] t) { p = t,} public IEnumerator GetEnumerator () { return new Myenumerator (P);}}
static void Main (string[] args) { Show ("-----------IEnumerator------------"); phone[] phones = new phone[] {new phone ("iphone 7s"), New phone ("iphone 6s"), New phone ("iphone 5s")}; Myenumerator enumerator = new Myenumerator (phones); while (enumerator. MoveNext ()) { Phone p = Enumerator. Current as Phone; Show (P.name); } Show ("-----------IEnumerable------------"); Phone phonelist = new phone (phones); foreach (Phone p in phonelist) { Show (p.name); } Console.readkey (); }
The results show:
Done, and then expanded into a common container phonepackage, inherit the generic Ienumerable<t> interface.
public class Phonepackage<t>: ienumerable<t> {private list<t> dataList = Null public void Add (T t) {if (dataList = = null) DataList = new list<t> (); Datalist.add (t); } public ienumerator<t> GetEnumerator () {foreach (T-T in DataList) {yield return T; }} IEnumerator Ienumerable.getenumerator () {foreach (T T in dataList) {yield return T; } } }
static void Main (string[] args) { Show ("-----------IEnumerator------------"); phone[] phones = new phone[] {new phone ("iphone 7s"), New phone ("iphone 6s"), New phone ("iphone 5s")}; Myenumerator enumerator = new Myenumerator (phones); while (enumerator. MoveNext ()) { Phone p = Enumerator. Current as Phone; Show (P.name); } Show ("-----------IEnumerable------------"); Phone phonelist = new phone (phones); foreach (Phone p in phonelist) { Show (p.name); } Show ("-----------ienumerable<t>------------"); phonepackage<phone> phonepackage = new phonepackage<phone> (); Phonepackage.add (New phone ("IPhone 7s")); Phonepackage.add (New phone ("IPhone 6s")); Phonepackage.add (New phone ("IPhone 5s")); foreach (Phone p in phonepackage) { Show (p.name); } Console.readkey (); } static void Show (String i) { Console.WriteLine (i);}
The results show:
The
IEnumerator iterator interface is verbose, and yield is the syntax sugar that simplifies traversal.