C # IEnumerator and IEnumerable

Source: Internet
Author: User

1, the use of the interface

(1) Define the interface first

          Public interface Ibattlemapmanager:           {                Stages currentstage {get;}                 Event eventhandler<beginfighteventargs> enterfight;          }

(2) Implementing a class with a definition-implementing an interface

public class Battlemapmanager:ibattlemapmanager, idisposable{public    Stages currentstage {get; private set;}    public event eventhandler<beginfighteventargs> Enterfight;    protected virtual void Onenterfight (Beginfighteventargs e)    {        var handler = enterfight;        if (handler! = null)            handler (this, e);    }    private void Trigger_triggered (object sender, Triggerevent.collidereventargs e)    {        var trigger = (triggerevent ) Sender;        var index = Fighttriggerevents.indexof (trigger);        trigger.enabled = false;        Onenterfight (New Beginfighteventargs (index));}    }

(3) Using an interface definition object to instantiate a class on an object with an interface-polymorphism

Partial class rootbattlestate{    private Ibattlemapmanager Battlemapmanager;    Private IEnumerator Initializebattleasync ()   {        Battlemapmanager = new Battlemapmanager ();        Battlemapmanager.enterfight + = Battlemapmanager_enterfight;
Battlemapmanager.loadmap (Stages.battlestage1); }}

IEnumerator: Provides an interface traversed in a normal collection, with Current,movenext (), Reset (), where current returns an object type.

IEnumerable: Exposes a IEnumerator that supports traversal in a normal collection.

Ienumerator<t>: Inherits from IEnumerator, has the current property, and returns the type T.

Ienumerable<t>: Inherits from IEnumerable, exposes a ienumerator<t>, supports traversal in a generic collection.

1. To enable the custom collection type to support foreach access, implement the IEnumerable interface.

2. In many places there are discussions about why the newly added generic interface ienumerable<t> to inherit IEnumerable, which is for compatibility.

theoretically, all generic interfaces are inherited from all non-generic interfaces. However special is that the ilist<t> does not inherit from the IList interface:

Because if you let ilist<t> inherit IList, then the class that implements ilist<int> needs to implement two insert methods,

One is ilist<int> void Insert (int index, int item),

One is the IList void Insert (int index, object item),

This is an interface that can insert data of type object into the Ilist<int> collection, which is not true, so it is not inherited.
And ienumerable<t> is different, it only "output" function, that is, we will only take data from it, so there is no confusion described above.

3. The following example describes how to use the
First, there is a person class:

public class person{public    string firstName;    public string lastName;    Public person (string fName, String lName)    {       this.firstname = fName;       This.lastname = LName;    } }

The first way to implement the People collection

public class people:ienumerable{private person[] _people;       Public people (person[] parray) {_people = new person[parray.length];       for (int i = 0; i < parray.length; i++) {_people[i] = Parray[i];    }} public IEnumerator GetEnumerator () {return new peopleenum (_people);      }} public class Peopleenum:ienumerator {public person[] _people;      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 (); }          }
}
}

The second way, let people oneself also implement IEnumerator interface:

public class people:ienumerable, ienumerator{private person[] _people;        int position =-1;            Public people (person[] parray) {_people = new person[parray.length];            for (int i = 0; i < parray.length; i++) {_people[i] = Parray[i];        }} #region IEnumerable IEnumerator GetEnumerator () {return this;             } #endregion #region IEnumerator members public object current {get                {try {return _people[position]; } catch (IndexOutOfRangeException) {throw new IndexOutOfRangeException ()                ;            }}} public bool MoveNext () {position++; Return (Position < _people.        Length); } public void Reset () {position =-1; } #endregion}

  The third way, the type is specified with generics:

public class People:ienumerable<person>, ienumerator<person>{private person[] _people;        int position =-1;            Public people (person[] parray) {_people = new person[parray.length];            for (int i = 0; i < parray.length; i++) {_people[i] = Parray[i];        }} #region ienumerable<person> members public ienumerator<person> GetEnumerator ()        {return this;            } #endregion #region IEnumerable members IEnumerator Ienumerable.getenumerator () {        return this;            } #endregion #region ienumerator<person> members, public person, current {get                {try {return _people[position]; } catch (IndexOutOfRangeException) {throw new IndexOutOfRangeException () ;               }}} #endregion #region IDisposable members public void Dispose ()            {} #endregion #region IEnumerator members object IEnumerator.Current {get                {try {return _people[position]; } catch (IndexOutOfRangeException) {throw new IndexOutOfRangeException ()                ;            }}} public bool MoveNext () {position++; Return (Position < _people.        Length);        } public void Reset () {position =-1; } #endregion}


You can then use foreach to access the custom collection:

person[] Peoplearray = new Person[3] {      new person ("John", "Smith"), the new person      ("Jim", "Johnson"), the      new person ("Sue", "Rabon"),}; People peoplelist = new people (Peoplearray); foreach (person p in peoplelist)     Console.WriteLine (P.firstname + "" + p.lastname);

The following describes the use of the yield keyword:

Note two points:

First: It can only be used in a iterator method, which means that the return value type of this method can only be ienumerable,ienumerator,ienumerable<t> or ienumerator<t>;

Second: It has only two kinds of syntax: yield return expression, or yield break;

(1) Use yield return to return each value in the loop that satisfies the condition, but does not exit the method:

public static class numberlist{public   static int[] INTs = {1, 2, 3, 5, 8,,, 144, 233, 377};    Define A property is returns only the even numbers.   public static ienumerable<int> Geteven ()   {        foreach (int i in ints)          if (i 2 = = 0)             yield return i;
   }}

The place to call is as follows:

Display the even numbers. Console.WriteLine ("Even Numbers"); foreach (int i in Numberlist.geteven ())   Console.WriteLine (i);

In this cycle of iterator, you can only exit the loop with yield break (and exit the entire method), if it is compiled with break:

public static ienumerable<int> Geteven () {   foreach (int i in ints)       if (i% 2 = = 0)          yield break;       Console.WriteLine ();}

If yield is break, it will be executed, then the Console.WriteLine () will not be executed, and the entire method body exits after the yield break has been executed.

(2) Another of the following:

Ienumerable<int> GetValues () {     yield return 1;     Yield return 2;     Yield return 3;     Yield return 4; } You can use foreach (int i in this.) GetValues ()) {    Console.WriteLine (i);}

To output, the first time to take the first yield return value 1, the second time to take the second yield return value 2, and so on

C # IEnumerator and IEnumerable

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.