Domanda

Una domanda di intervista per un lavoro .NET 3.5 è "Qual è la differenza tra un iteratore e un enumeratore"?

Questa è una distinzione fondamentale da fare, cosa con LINQ, ecc.

Comunque, qual è la differenza?Non riesco a trovare una definizione solida in rete.Non commettere errori, riesco a trovare il significato dei due termini ma ottengo risposte leggermente diverse.Quale sarebbe la risposta migliore per un colloquio?

IMO un iteratore "itera" su una raccolta e un enumeratore fornisce la funzionalità per iterare, ma questo deve essere chiamato.

Inoltre, si dice che l'utilizzo della parola chiave yield salvi lo stato.Cos'è esattamente questo stato?Esiste un esempio di questo beneficio?

È stato utile?

Soluzione

Iterare significa ripetere alcuni passaggi, mentre enumerare significa esaminare tutti i valori in una raccolta di valori.Quindi l'enumerazione di solito richiede una qualche forma di iterazione.

In questo modo, l'enumerazione è un caso speciale di iterazione in cui il passaggio ottiene un valore da una raccolta.

Nota il "di solito": l'enumerazione può anche essere eseguita in modo ricorsivo, ma la ricorsione e l'iterazione sono così strettamente correlate che non mi importerebbe questa piccola differenza.

Puoi anche enumerare valori che non memorizzi esplicitamente in una raccolta.Ad esempio, puoi enumerare il numero naturale, i numeri primi o qualsiasi altra cosa, ma calcolerai questi valori durante l'enumerazione e non li recupererai da una raccolta fisica.In questo caso intendi l'enumerazione di una raccolta virtuale con i suoi valori definiti da una logica.


Presumo che Reed Copsey abbia capito il punto.In C# esistono due modi principali per enumerare qualcosa.

  1. Strumento Enumerable e un'implementazione di classe IEnumerator
  2. Implementare un iteratore con il file yield dichiarazione

Il primo modo è più difficile da implementare e utilizza oggetti per l'enumerazione.Il secondo modo è più semplice da implementare e utilizza le continuazioni.

Altri suggerimenti

In C # 2+, iteratori sono un modo per il compilatore di generare automaticamente l'IEnumerable e / o IEnumerable interfacce per voi.

Senza iteratori, si avrebbe bisogno di creare una classe che implementa IEnumerator , tra cui corrente, MoveNext, e reset. Ciò richiede una buona dose di lavoro. Normalmente, si dovrebbe creare una classe privata che implemtented IEnumerator per il tipo, poi yourClass.GetEnumerator () sarebbe costruire quella classe privata, e restituirlo.

Gli iteratori sono un modo per il compilatore di generare automaticamente questo per voi, utilizzando una semplice sintassi (resa). Questo consente di implementare GetEnumerator () direttamente nella classe, senza un secondo di classe (L'IEnumerator) viene specificato da voi. La costruzione di quella classe, con tutti i suoi membri, è fatto per voi.

Gli iteratori sono molto sviluppatore amichevole - le cose sono fatte in modo molto efficiente, con molto meno sforzo

.

Quando si utilizza foreach, i due si comportano in modo identico (a condizione che si scrive correttamente la vostra abitudine IEnumerator). Iteratori solo rendere la vita molto più semplice.

Cosa C # chiama un iteratore è più comunemente (al di fuori del mondo C #) chiamato un generatore generatore (ad esempio in Python) o. Una funzione di generatore è un caso specializzato di coroutine . A C # iteratore (generatore) è una forma speciale di un enumeratore (un tipo di dati che implementa l'interfaccia IEnumerable).

Non mi piace questo uso del iteratore termine per un generatore di C #, perché è tanto un enumeratore in quanto è un iteratore. Troppo tardi per Microsoft di cambiare la sua mente, però.

Per contrasto ritengono che in C ++ un iteratore è un valore che viene utilizzato principalmente per accedere agli elementi sequenziali in una collezione. Esso può essere avanzata, derferenced per recuperare un valore, e testato per vedere se la fine della raccolta è stato raggiunto.

Per comprendere gli iteratori dobbiamo prima comprendere gli enumeratori.

Gli enumeratori sono oggetti specialistici che forniscono i mezzi per spostarsi attraverso un elenco ordinato di elementi uno alla volta (lo stesso tipo di cose è talvolta chiamato "cursore").Il framework .NET fornisce due importanti interfacce relative agli enumeratori:IEnumerator e IEnumerable.Gli oggetti che implementano IEnumerator sono essi stessi enumeratori;supportano i seguenti membri:

  • la proprietà Current, che punta ad una posizione nell'elenco

  • il metodo MoveNext, che sposta l'elemento corrente di uno nell'elenco

  • il metodo Reset, che sposta l'elemento corrente nella sua posizione iniziale (che è prima del primo elemento).

D'altra parte, gli Iteratori implementano il modello dell'enumeratore..NET 2.0 ha introdotto l'iteratore, che è un enumeratore manifesto del compilatore.Quando l'oggetto enumerabile chiama GetEnumerator, direttamente o indirettamente, il compilatore genera e restituisce un oggetto iteratore appropriato.Facoltativamente, l'iteratore può essere un oggetto combinato enumerabile ed enumeratore.

L'ingrediente essenziale di un blocco iteratore è la dichiarazione di rendimento.C'è una grande differenza tra iteratori ed enumeratori:Gli iteratori non implementano il metodo Reset.La chiamata al metodo Reset su un iteratore provoca un'eccezione.

Lo scopo degli iteratori è consentire la facile implementazione degli enumeratori.Laddove un metodo deve restituire un enumeratore o una classe enumerabile per un elenco ordinato di elementi, viene scritto in modo da restituire ciascun elemento nel suo ordine corretto utilizzando l'istruzione "yield".

"considerando che un istruzione foreach è il consumatore del enumeratore, un iteratore è il produttore del enumeratore".

È possibile che questo è il modo "C # 5.0 in a Nutshell" spiega, ed è stato utile per me.

In altre parole, l'istruzione foreach utilizza MoveNext (), e la proprietà attuale della IEnumerator per scorrere una sequenza, mentre l'iteratore viene usato per produrre l'attuazione del IEnumerator che verrà utilizzato dal foreach. In C #, quando si scrive un metodo iteratore contenente una dichiarazione resa, il compilatore genererà un enumeratore privato per voi. E quando si scorrere attraverso le voci nella sequenza, si chiamerà il MoveNext () e la proprietà corrente dell'enumeratore privato. Questi metodi / proprietà sono implementati dal codice nel metodo iteratore che verrà chiamato repeately a dare valori fino a quando non ci sono valori lasciati a cedere.

Questa è la mia comprensione di come C # definire enumeratori, e iteratori.

Dal momento che non sono stati forniti esempi, qui è uno che è stato utile per me.

Un enumeratore è un oggetto che si ottiene quando si chiama .GetEnumerator () su una classe o un tipo che implementa l'interfaccia IEnumerator. Quando questa interfaccia è implementata, è stato creato tutto il codice necessario per il compilor per consentire di utilizzare foreach a "iterare" sopra la vostra collezione.

Non ottenere quella parola 'iterare" confusi con iteratore però. Sia l'Enumerator e l'iteratore consentono di 'iterare'. L'enumerazione e iterazione sono fondamentalmente lo stesso processo, ma sono implementati in modo diverso. Enumerazione significa che hai impleneted l'interfaccia IEnumerator. Iterazione significa aver creato il costrutto iteratore nella classe (illustrato di seguito), e si sta chiamando foreach sulla tua classe, momento in cui il compilor crea automaticamente la funzionalità enumeratore per voi.

Si noti inoltre che non si ha a che fare con la vostra casa occupata enumeratore. È possibile chiamare MyClass.GetEnumerator() tutto il giorno, e non fare nulla con esso (esempio:

IEnumerator myEnumeratorThatIWillDoNothingWith = MyClass.GetEnumerator()).

Nota anche che il vostro iteratore costruire nella classe unica davvero si abitua quando si effettua la connessione, vale a dire che hai chiamato foreach sulla tua classe.

Ecco un esempio iteratore da MSDN :

public class DaysOfTheWeek : System.Collections.IEnumerable
{

     string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };

     //This is the iterator!!!
     public System.Collections.IEnumerator GetEnumerator()
     {
         for (int i = 0; i < days.Length; i++)
         {
             yield return days[i];
         }
     }

}

class TestDaysOfTheWeek
{
    static void Main()
    {
        // Create an instance of the collection class
        DaysOfTheWeek week = new DaysOfTheWeek();

        // Iterate with foreach - this is using the iterator!!! When the compiler
        //detects your iterator, it will automatically generate the Current, 
        //MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface
        foreach (string day in week)
        {
            System.Console.Write(day + " ");
        }
    }
}
// Output: Sun Mon Tue Wed Thr Fri Sat

"Gli iteratori sono una nuova funzionalità di C # 2.0. Un iteratore è un metodo, di accesso get o un operatore che consente di supportare l'iterazione foreach in una classe o struct, senza dover implementare l'intera interfaccia IEnumerable. Al contrario, è necessario fornire solo un iteratore, che attraversa semplicemente le strutture dati della tua classe. Quando il compilatore rileva l'iteratore, genererà automaticamente la corrente, MoveNext e Dispose metodi dell'interfaccia IEnumerable o IEnumerable ". - MSDN

offerte enumerazione di oggetti, mentre le offerte di iterazione con solo i valori. Enumeration viene utilizzato quando usiamo vettore tabella hash ecc mentre l'iterazione sono utilizzati in ciclo while ciclo for, ecc non ho mai usato la parola resa quindi non saprei dirti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top