Domanda

Io uso il seguente codice per attivare myClass per usare foreach. Ma io sono piuttosto nuovo per la programmazione e avere qualche difficoltà nel comprendere il seguente codice. Ho descritto i miei problemi nei commenti. Sarei grato per la fornitura di alcune informazioni.

    public class MyClass : IEnumerable<string> 
    {  
    //1) What is IEnumerator for?
        // Whats the difference between IEnumerator and IEnumerable
    public IEnumerator<string> GetEnumerator()     
    {
             yield return "first";         
             yield return "second";     
    }      
    //2) What is it for?  It just calls above method 
   IEnumerator IEnumerable.GetEnumerator()
         {
             return GetEnumerator(); 
         } 
    }
   //3) Lastly what benefits I have from implementing genetic interface 
   //IEnumerable<string> instead of just IEnumerable
È stato utile?

Soluzione

Qual è la differenza tra IEnumerator e IEnumerable?

La risposta di Jason è buona, ma ho pensato solo aggiungere come penso a questo. Immaginate di avere una sequenza:

1, 1, 2, 3, 5, 8, 13, ...

Ora immaginate di avere una freccia che punta in una qualche posizione di tale sequenza:

1, 1, 2, 3, 5, 8, 13, ...
         ^

Una "freccia" è un oggetto che può fare due cose. In primo luogo, si può dare la cosa si sta puntando. In secondo luogo, può farsi punto alla prossima cosa.

IEnumerator è una freccia. Ha una proprietà, attuale, che ti dà la cosa si sta puntando. Ha un metodo MoveNext () che si fa punto alla prossima cosa.

Come si ottiene una freccia, in primo luogo? Hai bisogno di una fabbrica di frecce. Si chiede alla fabbrica per una freccia, e ti dà una freccia che punta al primo elemento della sequenza.

IEnumerable è una fabbrica di frecce. Ha un metodo GetEnumerator, che ti dà una freccia al primo elemento della sequenza.

Una bella proprietà di questo schema è che si può avere più frecce che puntano a diversi posti nella stessa sequenza.

quali sono i vantaggi di attuazione generica interfaccia IEnumerable invece di IEnumerable?

Supponiamo che la sequenza è di interi. Se si implementa IEnumerable poi quando dici

foreach(int x in mysequence)

quello che effettivamente fare è convertire l'int nella sequenza all'oggetto, boxe il numero intero, e quindi immediatamente Unbox retro oggetto intero, aggiungendo un'allocazione di memoria completamente superfluo ogni singola operazione. Se il compilatore sa che la sequenza è di interi allora può saltare l'operazione di boxe non necessaria.

Supponiamo che la sequenza è di stringhe. Se si implementa IEnumerable<string> allora si può dire:

string first = mysequence.First();

Se non lo fai, allora si deve dire

string first = (string)mysequence.First();

che è inutile e soggetto a errori. Piuttosto che il compilatore tramite un cast che il tipo è stringa, si può semplicemente garanzia che il tipo è stringa utilizzando il sistema tipo.

Altri suggerimenti

1) Cosa è IEnumerator per? Qual'è la differenza tra IEnumerator e IEnumerable?

IEnumerator è un'interfaccia che rappresenta i metodi che consentono di enumerare una sequenza. La differenza tra IEnumerator e IEnumerable è che il primo rappresenta il contratto per gli oggetti che consentono di enumerare una sequenza, e il secondo rappresenta il contratto per gli oggetti che sono una sequenza che può essere enumerato sopra.

public IEnumerator<string> GetEnumerator() {
         yield return "first";         
         yield return "second";     
}      


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

2) A cosa serve? Si chiama proprio sopra metodo.

Il primo rappresenta un'implementazione del metodo GetEnumerator sul IEnumerable<string> contratto. Quest'ultimo rappresenta un'implementazione esplicita del metodo GetEnumerator sul IEnumerable contratto. Il problema è che entrambi i contratti hanno un metodo denominato GetEnumerator ma con differenti tipi di ritorno in modo che un metodo non può soddisfare contemporaneamente sia i contratti (qualsiasi IEnumerable<T> attuazione classe deve implementare anche IEnumerable come IEnumerable<T> : IEnumerable). Quest'ultimo invoca l'attuazione di IEnumerable<string>.GetEnumerator come quello è un'implementazione ragionevole che restituisce un IEnumerator come IEnumerator<string> : IEnumerator.

3) Infine quali benefici che ho da attuare IEnumerable<string> un'interfaccia generica invece di IEnumerable?

tipizzazione forte. Voi sapete che gli elementi di una sequenza di IEnumerable<string> sono tutte le istanze di String, mentre non si sa che, per IEnumerable e potrebbe finire per cercare di lanciare un elemento di quest'ultimo a un'istanza di String quando non può essere.

Questa è la dichiarazione per IEnumerable<T>:

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

Non hai scelta, è sono per implementare l'interfaccia IEnumerable non generico pure. Si otterrà un errore di compilazione, se si omette l'attuazione IEnumerable.GetEnumerator (). Questo è il bagaglio lasciati dai giorni 1.x .NET in cui i farmaci generici non erano ancora disponibili e il periodo di transizione per NET 2.0 dove doveva supportare l'interoperabilità con .NET 1.x assemblee. Siamo bloccati con esso.

1) Qual è IEnumerator per?

IEnumerator è la parte di lavoro vero e proprio con il MoveNext () ei membri attuali.

Qual'è la differenza tra IEnumerator e IEnumerable

IEnumerable è l'interfaccia per una collezione di segnale che ha un GetEnumerator ().

2) [GetEnumerator non generico] A cosa serve? Si chiama proprio sopra il metodo

Il metodo non generico è lì per la compatibilità all'indietro. Si noti che viene spostato 'da vista', per quanto possibile con l'uso della realizzazione esplicita. Implementare perché è necessario e poi non pensarci più.

3) Infine quali benefici che ho da implementare un'interfaccia genetica IEnumerable invece di IEnumerable

Quando utilizzato con il foreach adavantage è piccolo, come foreach scriverà pressofuso la variabile loop. Essa vi permetterà di utilizzare var nel foreach:

foreach (var s in myClassInstance)     // needs `IEnumerable<string>` 
foreach (string s in myClassInstance)  // works with  `IEnumerable` as well 

Ma con IEnumerable<string> si hanno anche un'interfaccia di tipo-safe ad altre aree, in particolare LINQ:

MyClass mc = new MyClass ();
string s = mc.FirstOrDefault();

GetEnumerator è stato intorno fin da prima generici sono stati introdotti alla lingua, in modo da non rompere il codice pre-esistente, le chiamate di metodo di default attraverso l'implementazione generica.

Con un'enumerazione generica, il consumatore della classe non ha bisogno di lanciare ogni voce di stringa quando l'iterazione.

Per quanto riguarda la terza domanda qui sono alcune risposte (perché uso farmaci generici?):

dovremmo usare insieme generico per migliorare la sicurezza e prestazioni?

In breve, utilizzare collezioni generici ogni volta che è possibile.

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