2010-10-14 12 views
18

Se ho un ciclo for come il seguente:Questo ciclo foreach chiama Split() ogni iterazione in C#?

foreach(string email in installerEmails.Split(',')) 
{ 
    Console.WriteLine(email); 
} 

disposta la Split() chiamata essere effettuato su ogni iterazione del ciclo? Devo memorizzarlo in un array temporaneo prima di iterarlo?

+3

+1: buona domanda –

+1

possibile duplicato di [Come funziona foreach durante il looping dei risultati delle funzioni?] (Http://stackoverflow.com/questions/1632810/how-does-foreach-work-when-looping-through -funzione-risultati) –

risposta

26

No. Verrà iterato sul risultato di quella chiamata, ovvero il tipo di ritorno di Split che è una serie di stringhe: string[].

1

Il Split verrà chiamato una volta, il che comporta una matrice. Il foreach quindi utilizza un singolo enumeratore per scorrere l'array.

+4

Ottimizza da cosa? È ciò che definisce il loop in primo luogo. –

+0

@Jon Hanna: Il mio errore, stavo pensando nel contesto di un ciclo while per un secondo. Non ottimizzerebbe nulla lì, che avrebbe vanificato lo scopo di 'while' :) L'ho rimosso dalla mia risposta, grazie. –

4

No. Basta eseguire il debug del codice. vedrai che il metodo Split() viene chiamato una sola volta.

0

No. .Split() restituisce un oggetto IEnumerable e che verrà utilizzato per iterare sopra.

5

Il risultato della divisione viene valutato una volta, quindi viene chiamato GetEnumerator(). Ciò restituisce un IEnumerator su cui viene chiamato il metodo MoveNext e la proprietà Current in ogni iterazione.

E 'fondamentalmente equivalente a:

string[] enumerable=installerEmails.Split(','); 
IEnumerator<string> enumerator=enumerable.GetEnumerator(); 
while(enumerator.MoveNext()) 
{ 
    string email=(string)enumerator.Current; 
    Console.WriteLine(email); 
} 

Una brutta dettaglio è il cast esplicito al tipo si dà nel ciclo for il compilatore genera. Questo era utile in C# 1.0 dove IEnumerator non era generico.

Ho dimenticato che l'Enumeratore viene eliminato. Vedi la risposta di Jon Hanna per il codice che include lo smaltimento.

3

No. L'oggetto restituito da Split (che si verifica essere un array, ma lo stesso vale per altri oggetti enumerabili) è ciò che definisce il ciclo dopo tutto. Se ha zero o un milione di elementi, è esso che sta definendo zero o milioni di iterazioni, che non potrebbe fare se continuasse a essere chiamato.

Per un po 'più in dettaglio, il codice prodotto diventa equivalente a:

string[] temp = installerEmails.Split(','); 
var enumerator = temp.GetEnumerator(); 
try 
{ 
    while(enumerator.MoveNext()) 
    { 
    string email = (string)enumerator.Current; 
    Console.WriteLine(email); 
    } 
} 
finally 
{ 
    if(enumerator is IDisposable) 
    ((IDisposable)enumerator).Dispose() 
} 

Come si può vedere, .Split() viene chiamato solo una volta.

Problemi correlati