Domanda

Qualcuno può spiegarmi IEnumerable e IEnumerator?

ad esempio, quando usarlo su foreach?qual è la differenza tra IEnumerable e IEnumerator?Perché dobbiamo usarlo?

È stato utile?

Soluzione

  

Ad esempio, quando usare sopra foreach?

Non si utilizza IEnumerable "over" foreach. Implementazione IEnumerable rende l'utilizzo foreach possibile .

Quando si scrive codice come:

foreach (Foo bar in baz)
{
   ...
}

è funzionalmente equivalente alla scrittura:

IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
   bar = (Foo)bat.Current
   ...
}

Con il termine "funzionalmente equivalente," Voglio dire che in realtà è quello che il compilatore trasforma il codice in. Non è possibile utilizzare foreach su baz in questo esempio meno baz implementa IEnumerable.

IEnumerable significa che baz implementa il metodo

IEnumerator GetEnumerator()

L'oggetto IEnumerator che questo metodo restituisce devono implementare i metodi

bool MoveNext()

e

Object Current()

Il primo metodo avanza al successivo oggetto nell'oggetto IEnumerable che ha creato l'enumeratore, tornando false se è fatto, e la seconda restituisce l'oggetto corrente.

Tutto ciò in .Net che si può iterare su attrezzi IEnumerable. Se si sta costruendo la propria classe, e non lo fa già ereditare da una classe che implementa IEnumerable, è possibile rendere la vostra classe utilizzabile nelle dichiarazioni foreach implementando IEnumerable (e con la creazione di una classe enumeratore che il suo nuovo metodo GetEnumerator tornerà) .

Altri suggerimenti

L'IEnumerable e IEnumerator Interfacce

Per iniziare esaminando il processo di implementazione delle interfacce .NET esistenti, si deve prima sguardo al ruolo del IEnumerable e IEnumerator. Ricordiamo che C # supporta una parola chiave denominata foreach che consente di iterare nel contenuto di qualsiasi tipo di matrice:

// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
   Console.WriteLine(i);
}

Anche se può sembrare che solo i tipi di array possono usufruire di questo costrutto, la verità della questione è qualsiasi tipo di supporto un metodo denominato GetEnumerator () può essere valutato dalla foreach construct.To illustrare, mi segua!

Supponiamo di avere una classe garage:

// Garage contains a set of Car objects.
public class Garage
{
   private Car[] carArray = new Car[4];
   // Fill with some Car objects upon startup.
   public Garage()
   {
      carArray[0] = new Car("Rusty", 30);
      carArray[1] = new Car("Clunker", 55);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
}

L'ideale sarebbe conveniente per scorrere gli elementi secondari dell'oggetto garage utilizzando il foreach costruire, proprio come una matrice di valori di dati:

// This seems reasonable ...
public class Program
{
   static void Main(string[] args)
   {
      Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****\n");
      Garage carLot = new Garage();
      // Hand over each car in the collection?
      foreach (Car c in carLot)
      {
         Console.WriteLine("{0} is going {1} MPH",
         c.PetName, c.CurrentSpeed);
      }
      Console.ReadLine();
   }
}

Purtroppo, il compilatore si informa che la classe garage non implementa un metodo denominato GetEnumerator (). Questo metodo è formalizzata dalla interfaccia IEnumerable, che si trova in agguato all'interno del namespace System.Collections. Le classi o strutture che supportano questo comportamento pubblicità che essi sono in grado di esporre contenuta elementi secondari al chiamante (in questo esempio, la parola chiave foreach stesso). Ecco la definizione di questa interfaccia standard NET:

// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
   IEnumerator GetEnumerator();
}

Come si può vedere, il metodo GetEnumerator () restituisce un riferimento a un altro nome di interfaccia System.Collections.IEnumerator. Questa interfaccia fornisce l'infrastruttura per consentire al chiamante di attraversare gli oggetti interni contenuti dal contenitore IEnumerable-compatibile:

// This interface allows the caller to
// obtain a container's subitems.
public interface IEnumerator
{
   bool MoveNext (); // Advance the internal position of the cursor.
   object Current { get;} // Get the current item (read-only property).
   void Reset (); // Reset the cursor before the first member.
}

Se si desidera aggiornare il Tipo di magazzino per supportare queste interfacce, è possibile prendere la strada lunga e implementare ogni metodo manualmente. Mentre si è certamente libero di fornire versioni personalizzate di GetEnumerator (), MoveNext (), Corrente, e Reset (), c'è un modo più semplice. Come il tipo System.Array (così come molte altre classi di raccolta) implementa già IEnumerable e IEnumerator, si può semplicemente delegare la richiesta al System.Array come segue:

using System.Collections;
...
public class Garage : IEnumerable
{
   // System.Array already implements IEnumerator!
   private Car[] carArray = new Car[4];
   public Garage()
   {
      carArray[0] = new Car("FeeFee", 200);
      carArray[1] = new Car("Clunker", 90);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
   public IEnumerator GetEnumerator()
   {
      // Return the array object's IEnumerator.
      return carArray.GetEnumerator();
   }
}

Dopo aver aggiornato il vostro tipo di garage, si può tranquillamente utilizzare il tipo all'interno del costrutto C # foreach. Inoltre, dato che il metodo GetEnumerator () è stato definito pubblicamente, l'utente oggetto può anche interagire con il tipo IEnumerator:

// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName, myCar.CurrentSpeed);

Tuttavia, se si preferisce nascondere la funzionalità della IEnumerable dal livello di oggetto, semplicemente fare uso di implementazione dell'interfaccia esplicita:

IEnumerator IEnumerable.GetEnumerator()
{
  // Return the array object's IEnumerator.
  return carArray.GetEnumerator();
}

In questo modo, l'utente oggetto casuale non troverà metodo GetEnumerator () del garage, mentre il foreach costrutto ottenere l'interfaccia in background quando necessario.

Pro C # 5.0 e .NET Framework 4.5

Implementazione IEnumerable significa che la vostra classe restituisce un oggetto IEnumerator:

public class People : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        // return a PeopleEnumerator
    }
}

Implementazione IEnumerator significa che la vostra classe restituisce i metodi e le proprietà per l'iterazione:

public class PeopleEnumerator : IEnumerator
{
    public void Reset()...

    public bool MoveNext()...

    public object Current...
}

Questa è la differenza comunque.

Spiegazione tramite analogia + procedura dettagliata del codice

Prima una spiegazione senza codice, poi la aggiungerò più tardi.

Supponiamo che tu gestisca una compagnia aerea.E in ogni aereo vuoi conoscere le informazioni sui passeggeri che volano sull'aereo.Fondamentalmente vuoi essere in grado di "attraversare" l'aereo.In altre parole, vuoi poter iniziare dal sedile anteriore, per poi procedere verso il retro dell'aereo, chiedendo ai passeggeri alcune informazioni:chi sono, da dove vengono, ecc.Un aereo può farlo solo se è:

  1. numerabile e
  2. se ha un contatore.

Perché questi requisiti? Perché è ciò che richiede l'interfaccia.

Se questo è un sovraccarico di informazioni, tutto ciò che devi sapere è che vuoi poter porre alcune domande a ciascun passeggero dell'aereo, iniziando dalla prima fino all'ultima.

Cosa significa numerabile?

Se una compagnia aerea è "contabile", significa che DEVE essere presente un assistente di volo sull'aereo, il cui unico compito è contare - e questo assistente di volo DEVE contare in un modo molto specifico:

  1. L'addetto al banco/assistente di volo DEVE iniziare prima del primo passeggero (davanti a tutti dove dimostra la sicurezza, come indossare il giubbotto di salvataggio, ecc.).
  2. Lui/lei (cioèl'assistente di volo) DEVE "spostarsi" lungo il corridoio fino al primo posto.
  3. Dovrà poi registrare:(i) chi è la persona seduta e (ii) la sua posizione attuale nel corridoio.

Procedure di conteggio

Il capitano della compagnia aerea vuole un rapporto su ogni passeggero man mano che viene indagato o conteggiato.Quindi, dopo aver parlato con la persona al primo posto, l'assistente di volo/banco fa rapporto al capitano e, una volta fatto il rapporto, il banco ricorda la sua esatta posizione nel corridoio e continua a contare esattamente da dove è partito spento.

In questo modo il capitano è sempre in grado di avere informazioni sulla persona attualmente indagata.In questo modo, se scopre che a questa persona piace il Manchester City, allora potrà concedere a quel passeggero un trattamento preferenziale, ecc.

  • Il contatore continua ad andare avanti finché non raggiunge la fine dell'aereo.

Colleghiamolo con IEnumerables

  • Un enumerabile è solo un insieme di passeggeri su un aereo.La legge sull'aviazione civile: queste sono fondamentalmente le regole che tutti gli IEnumerables devono seguire.Ogni volta che l'assistente di volo si reca dal capitano con le informazioni sul passeggero, in pratica stiamo "cedendo" il passeggero al capitano.Il capitano può sostanzialmente fare quello che vuole con il passeggero, tranne riorganizzare i passeggeri sull'aereo.In questo caso hanno un trattamento preferenziale se seguono il Manchester City (ugh!)

    foreach (Passenger passenger in Plane)
    // the airline hostess is now at the front of the plane
    // and slowly making her way towards the back
    // when she get to a particular passenger she gets some information
    // about the passenger and then immediately heads to the cabin
    // to let the captain decide what to do with it
    { // <---------- Note the curly bracket that is here.
        // we are now cockpit of the plane with the captain.
        // the captain wants to give the passenger free 
        // champaign if they support manchester city
        if (passenger.supports_mancestercity())
        {
            passenger.getFreeChampaign();
        } else
        {
            // you get nothing! GOOD DAY SIR!
        }
    } //  <---- Note the curly bracket that is here!
          the hostess has delivered the information 
          to the captain and goes to the next person
          on the plane (if she has not reached the 
          end of the plane)
    

Riepilogo

In altre parole, qualcosa è numerabile se esso ha un contatore.E il contatore deve (sostanzialmente):(i) ricordare il suo posto (stato), (ii) essere in grado di spostati avanti, (iii) e conoscere il attuale persona con cui ha a che fare.

Enumerabile è solo una parola elegante per "numerabile".In altre parole, un enumerabile ti consente di "enumerare" (cioècontare).

IEnumerable implementa GetEnumerator. Quando viene chiamato, questo metodo restituirà un IEnumerator che implementa MoveNext, reset e attuale.

Così, quando la classe implementa IEnumerable, lei sta dicendo che si può chiamare un metodo (GetEnumerator) e ottenere un nuovo oggetto restituito (un IEnumerator) è possibile utilizzare in un ciclo come foreach.

Implementazione IEnumerable consente di ottenere un IEnumerator per una lista.

IEnumerator permette stile foreach accesso sequenziale agli elementi della lista, utilizzando la parola chiave di rendimento.

Prima di implementazione foreach (in Java 1.4, per esempio), il modo per scorrere una lista era quello di ottenere un enumeratore dalla lista, poi chiedere per il "prossimo" elemento nella lista, per tutto il tempo il valore restituito come l'elemento successivo non è nullo. Foreach fa semplicemente che implicitamente come una caratteristica del linguaggio, nello stesso modo in cui bloccare () implementa la classe Monitor dietro le quinte.

Mi aspetto foreach funziona su liste perché implementano IEnumerable.

  • Un oggetto che implementa IEnumerable permette ad altri di visitare ciascuno dei suoi elementi (da un enumeratore) .
  • Un oggetto applicazione IEnumerator è il fare l'iterazione. E 'un ciclo su un oggetto enumerabile.

Pensate di oggetti enumerabili come di liste, pile, alberi.

IEnumerable e IEnumerator (e le loro controparti generiche IEnumerable<T> e IEnumerator<T>) sono interfacce di base di iteratore implementazioni in Raccolte di librerie di classi .Net Framework.

IEnumerabile è l'interfaccia più comune che vedresti nella maggior parte del codice disponibile.Abilita il ciclo foreach, i generatori (pensa prodotto) e grazie alla sua piccola interfaccia, viene utilizzato per creare astrazioni strette. IEnumerable dipende da IEnumerator.

IEnumerator, d'altro canto, fornisce un'interfaccia di iterazione di livello leggermente inferiore.Viene indicato come iteratore esplicito che offre al programmatore un maggiore controllo sul ciclo di iterazione.

IEnumerabile

IEnumerable è un'interfaccia standard che consente l'iterazione sulle raccolte che la supportano (in effetti, tutti i tipi di raccolta a cui riesco a pensare oggi implementano IEnumerabile).Il supporto del compilatore consente funzionalità linguistiche come foreach.In termini generali, ciò lo consente implementazione implicita dell'iteratore.

foreach Loop

foreach (var value in list)
  Console.WriteLine(value);

Penso foreach loop è uno dei motivi principali per l'utilizzo IEnumerabile interfacce. foreach ha una sintassi molto concisa e molto facile da capire rispetto a quella classica C stile for loop in cui è necessario controllare le varie variabili per vedere cosa stava facendo.

produrre la parola chiave

Probabilmente una caratteristica meno conosciuta è questa IEnumerabile consente anche generatori in C# con l'uso di yield return E yield break dichiarazioni.

IEnumerable<Thing> GetThings() {
   if (isNotReady) yield break;
   while (thereIsMore)
     yield return GetOneMoreThing();
}

Astrazioni

Un altro scenario comune nella pratica è l'utilizzo IEnumerabile per fornire astrazioni minimaliste.Poiché si tratta di un'interfaccia minuscola e di sola lettura, sei incoraggiato a esporre le tue raccolte come IEnumerabile (piuttosto che Elenco Per esempio).In questo modo sei libero di modificare la tua implementazione senza infrangere il codice del tuo cliente (cambia List in a Lista collegata ad esempio).

Capito

Un comportamento di cui tenere presente è che nelle implementazioni di streaming (ad es.recuperando i dati riga per riga da un database, invece di caricare prima tutti i risultati in memoria). non può ripetere la raccolta più di una volta.Ciò è in contrasto con le raccolte in memoria come Elenco, dove puoi ripetere più volte senza problemi.ReSharper, ad esempio, ha un'ispezione del codice per Possibile enumerazione multipla di IEnumerable.

IEnumerator

IEnumerator, d'altra parte, è l'interfaccia dietro le quinte che rende IEnumerble-foreach-magic lavoro.A rigor di termini, abilita iteratori espliciti.

var iter = list.GetEnumerator();
while (iter.MoveNext())
    Console.WriteLine(iter.Current);

Nella mia esperienza IEnumerator è usato raramente in scenari comuni a causa della sua sintassi più dettagliata e della semantica leggermente confusa (almeno per me;per esempio. SpostaAvanti() restituisce anche un valore, che il nome non suggerisce affatto).

Caso d'uso per IEnumerator

Ho solo usato IEnumerator in particolare (di livello leggermente inferiore) librerie e framework in cui fornivo IEnumerabile interfacce.Un esempio è una libreria di elaborazione del flusso di dati che fornisce una serie di oggetti in a foreach loop anche se i dati dietro le quinte sono stati raccolti utilizzando vari flussi di file e serializzazioni.

Codice cliente

foreach(var item in feed.GetItems())
    Console.WriteLine(item);

Biblioteca

IEnumerable GetItems() {
    return new FeedIterator(_fileNames)
}

class FeedIterator: IEnumerable {
    IEnumerator GetEnumerator() {
        return new FeedExplicitIterator(_stream);
    }
}

class FeedExplicitIterator: IEnumerator {
    DataItem _current;

    bool MoveNext() {
        _current = ReadMoreFromStream();
        return _current != null;           
    }

    DataItem Current() {
        return _current;   
    }
}

IEnumerable Attuazione significa in sostanza che l'oggetto può essere iterato. Questo non significa necessariamente che si tratta di un array come ci sono alcune liste che non possono essere indicizzati, ma li si può enumerare.

IEnumerator è l'oggetto effettivo utilizzato per eseguire le iterazioni. Esso controlla lo spostamento da un oggetto al successivo nell'elenco.

La maggior parte del tempo, IEnumerable & IEnumerator sono utilizzati in modo trasparente come parte di un ciclo foreach.

Differenze tra IEnumerable e IEnumerator:

  • IEnumerable utilizza internamente IEnumerator.
  • doesnt IEnumerable sapere quale oggetto / oggetto è in esecuzione.
  • Ogni volta che passiamo IEnumerator a un'altra funzione, si conosce la posizione attuale del punto / oggetto.
  • Ogni volta che passiamo insieme IEnumerable a un'altra funzione, è non conosce la posizione attuale del punto / oggetto (non sa quale voce la sua esecuzione)

    IEnumerable ha un metodo GetEnumerator ()

public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}

IEnumerator avere una proprietà attuale e due metodi Reset e MoveNext (che è utile per conoscere la posizione corrente di un elemento in una lista).

public interface IEnumerator
{
     object Current { get; }
     bool MoveNext();
     void Reset();
}

La comprensione del modello Iterator sarà utile per voi. Vi consiglio di leggere la stessa.

Iterator modello

A un livello elevato, il modello iteratore può essere utilizzato per fornire un modo standard di iterazione attraverso collezioni di qualsiasi tipo. Abbiamo 3 partecipanti al modello iteratore, la collezione reale (client), l'aggregatore e l'iteratore. L'aggregato è una classe di interfaccia / astratta che ha un metodo che restituisce un iteratore. Iterator è una classe di interfaccia / astratta che ha metodi che ci permette di scorrere una collezione.

Al fine di implementare il modello abbiamo prima bisogno di implementare un iteratore per produrre un calcestruzzo in grado di scorrere sopra la collezione in questione (client) Poi la collezione (client) implementa l'aggregatore di restituire un'istanza della iteratore sopra.

Ecco il diagramma UML Iterator pattern

Quindi, fondamentalmente in C #, IEnumerable è l'aggregato astratto e IEnumerator è l'Iterator astratto. IEnumerable ha un unico metodo GetEnumerator che è responsabile della creazione di un'istanza di IEnumerator del tipo desiderato. Collezioni come le liste implementano l'interfaccia IEnumerable.

Esempio. Consente di supporre che abbiamo un metodo di getPermutations(inputString) che restituisce tutte le permutazioni di una stringa e che il metodo restituisce un'istanza di IEnumerable<string>

Al fine di contare il numero di permutazioni che potevamo fare qualcosa di simile al di sotto.

 int count = 0;
        var permutations = perm.getPermutations(inputString);
        foreach (string permutation in permutations)
        {
            count++;
        }

Il compilatore C # più o meno converte il sopra per

using (var permutationIterator = perm.getPermutations(input).GetEnumerator())
        {
            while (permutationIterator.MoveNext())
            {
                count++;
            }
        }

Se avete domande non esitate a chiedere.

IEnumerable è una scatola che contiene IEnumerator. IEnumerable è interfaccia di base per tutte le collezioni. ciclo foreach può funzionare se la raccolta implementa IEnumerable. Nel codice di seguito spiega il passo di avere il nostro Enumerator. Consente innanzitutto definire la nostra classe di cui ci accingiamo a fare la raccolta.

public class Customer
{
    public String Name { get; set; }
    public String City { get; set; }
    public long Mobile { get; set; }
    public double Amount { get; set; }
}

Ora si definire la classe che fungerà da una collezione per la nostra classe Cliente. Si noti che sta attuando l'interfaccia IEnumerable. In modo che dobbiamo implementare il metodo GetEnumerator. Ciò restituirà la nostra Enumerator personalizzato.

public class CustomerList : IEnumerable
{
    Customer[] customers = new Customer[4];
    public CustomerList()
    {
        customers[0] = new Customer { Name = "Bijay Thapa", City = "LA", Mobile = 9841639665, Amount = 89.45 };
        customers[1] = new Customer { Name = "Jack", City = "NYC", Mobile = 9175869002, Amount = 426.00 };
        customers[2] = new Customer { Name = "Anil min", City = "Kathmandu", Mobile = 9173694005, Amount = 5896.20 };
        customers[3] = new Customer { Name = "Jim sin", City = "Delhi", Mobile = 64214556002, Amount = 596.20 };
    }

    public int Count()
    {
        return customers.Count();
    }
    public Customer this[int index]
    {
        get
        {
            return customers[index];
        }
    }
    public IEnumerator GetEnumerator()
    {
        return customers.GetEnumerator(); // we can do this but we are going to make our own Enumerator
        return new CustomerEnumerator(this);
    }
}

Ora stiamo andando a creare la nostra enumeratore personalizzato come segue. Quindi, dobbiamo implementare il metodo MoveNext.

 public class CustomerEnumerator : IEnumerator
    {
        CustomerList coll;
        Customer CurrentCustomer;
        int currentIndex;
        public CustomerEnumerator(CustomerList customerList)
        {
            coll = customerList;
            currentIndex = -1;
        }

        public object Current => CurrentCustomer;

        public bool MoveNext()
        {
            if ((currentIndex++) >= coll.Count() - 1)
                return false;
            else
                CurrentCustomer = coll[currentIndex];
            return true;
        }

        public void Reset()
        {
            // we dont have to implement this method.
        }
    }

Ora possiamo usare ciclo foreach sopra la nostra collezione come qui di seguito;

    class EnumeratorExample
    {
        static void Main(String[] args)
        {

            CustomerList custList = new CustomerList();
            foreach (Customer cust in custList)
            {
                Console.WriteLine("Customer Name:"+cust.Name + " City Name:" + cust.City + " Mobile Number:" + cust.Amount);
            }
            Console.Read();

        }
    }

Un contributo minore.

Come molti di loro spiegare su 'quando usare' e 'usare con foreach'. Ho pensato di aggiungere un altro Uniti Differenza qui come richiesto nella domanda circa la differenza tra i due IEnumerable un IEnumerator.

Ho creato il codice di esempio qui di seguito sulla base dei thread di discussione qui sotto.

IEnumerable, IEnumerator vs foreach, quando usare cosa Qual è la differenza tra IEnumerator e IEnumerable?

enumeratore preserva lo stato (posizione iterazione) tra funzione chiama mentre iterazioni invece Enumerable no.

Ecco l'esempio testato con i commenti per capire.

Gli esperti si prega di aggiungere / mi corregga.

static void EnumerableVsEnumeratorStateTest()
{
    IList<int> numList = new List<int>();

    numList.Add(1);
    numList.Add(2);
    numList.Add(3);
    numList.Add(4);
    numList.Add(5);
    numList.Add(6);

    Console.WriteLine("Using Enumerator - Remembers the state");
    IterateFrom1to3(numList.GetEnumerator());

    Console.WriteLine("Using Enumerable - Does not Remembers the state");
    IterateFrom1to3Eb(numList);

    Console.WriteLine("Using Enumerable - 2nd functions start from the item 1 in the collection");
}

static void IterateFrom1to3(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());

        if (numColl.Current > 3)
        {
            // This method called 3 times for 3 items (4,5,6) in the collection. 
            // It remembers the state and displays the continued values.
            IterateFrom3to6(numColl);
        }
    }
}

static void IterateFrom3to6(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());
    }
}

static void IterateFrom1to3Eb(IEnumerable<int> numColl)
{
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());

        if (num>= 5)
        {
            // The below method invokes for the last 2 items.
            //Since it doesnot persists the state it will displays entire collection 2 times.
            IterateFrom3to6Eb(numColl);
        }
    }
}

static void IterateFrom3to6Eb(IEnumerable<int> numColl)
{
    Console.WriteLine();
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());
    }
}

ho notato queste differenze:

A. Iteriamo la lista in modo diverso, foreach può essere utilizzato per IEnumerable e mentre ciclo per IEnumerator.

B. IEnumerator riesce a ricordare l'indice corrente quando si passa da un metodo all'altro (è iniziare a lavorare con indice corrente), ma IEnumerable non riesce a ricordare l'indice e reimpostare l'indice all'inizio. Più in questo video https://www.youtube.com/watch?v=jd3yUjGc9M0

IEnumerable e IEnumerator entrambi sono interfacce in C #.

IEnumerable è un'interfaccia che definisce un unico metodo GetEnumerator() che restituisce un'interfaccia IEnumerator.

Questo funziona per l'accesso in sola lettura ad una collezione che implementa che IEnumerable può essere utilizzato con una dichiarazione foreach.

IEnumerator ha due metodi, MoveNext e Reset. Essa ha anche una proprietà chiamata Current.

Quanto segue mostra l'implementazione di IEnumerable e IEnumerator.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Enudemo
{

    class Person
    {
        string name = "";
        int roll;

        public Person(string name, int roll)
        {
            this.name = name;
            this.roll = roll;
        }

        public override string ToString()
        {
            return string.Format("Name : " + name + "\t Roll : " + roll);
        }

    }


    class Demo : IEnumerable
    {
        ArrayList list1 = new ArrayList();

        public Demo()
        {
            list1.Add(new Person("Shahriar", 332));
            list1.Add(new Person("Sujon", 333));
            list1.Add(new Person("Sumona", 334));
            list1.Add(new Person("Shakil", 335));
            list1.Add(new Person("Shruti", 336));
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
           return list1.GetEnumerator();
        }
    }



    class Program
    {
        static void Main(string[] args)
        {
            Demo d = new Demo();  // Notice here. it is simple object but for 
                                //IEnumerator you can get the collection data

            foreach (Person X in d)
            {
                Console.WriteLine(X);
            }

            Console.ReadKey();
        }
    }
}
/*
Output : 

Name : Shahriar  Roll : 332
Name : Sujon     Roll : 333
Name : Sumona    Roll : 334
Name : Shakil    Roll : 335
Name : Shruti    Roll : 336
  */
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top