2010-10-14 6 views
18

Si tengo un bucle como el siguiente:¿Este bucle foreach llamará a Split() cada iteración en C#?

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

aumentará la división() llame a cabo en cada iteración del bucle? ¿Debo almacenarlo en una matriz temporal antes de recorrerlo?

+3

+1: buena pregunta –

+1

posible duplicado de [¿Cómo funciona Foreach al alternar entre los resultados de la función?] (Http://stackoverflow.com/questions/1632810/how-does-foreach-work-when-looping-through -function-results) –

Respuesta

26

No. Repite el resultado de esa llamada, es decir, el tipo de devolución de Split que es una matriz de cadenas: string[].

1

Se llamará al Split una vez, lo que da como resultado una matriz. El foreach luego usa un solo enumerador para iterar sobre la matriz.

+4

Optimizarlo de qué? Es lo que está definiendo el ciclo en primer lugar. –

+0

@Jon Hanna: Mi error, estaba pensando en el contexto de un ciclo while por un segundo. No optimizaría nada allí, eso vencería el propósito de 'while' :) Lo eliminé de mi respuesta, gracias. –

4

No. Simplemente elimine su código. verá que el método Split() solo se llama una vez.

0

No. .Split() devuelve un IEnumerable y se usará para iterar.

5

El resultado de Split se evalúa una vez, luego se llama a GetEnumerator(). Esto devuelve un IEnumerator en el que se llama el método MoveNext y la propiedad Current en cada iteración.

es básicamente equivalente a:

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

Un feo detalle es la conversión explícita al tipo le da en el bucle genera el compilador. Esto fue útil en C# 1.0 donde IEnumerator no era genérico.

Olvidé que el Enumerator se desecha. Ver la respuesta de Jon Hanna para el código que incluye deshacerse.

3

No. El objeto devuelto por Split (que pasa a ser una matriz, pero lo mismo se aplica a otros objetos enumerables) es lo que define el ciclo después de todo. Si tiene cero o un millón de elementos, es el que define el cero o el millón de iteraciones, lo que no podría hacer si siguiera llamándose.

Para un poco más de detalle, el código producido se convierte en 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() 
} 

Como se puede ver, .Split() se llama sólo una vez.

Cuestiones relacionadas