2011-11-02 15 views
5

¿Alguien puede explicar por qué la siguiente línea de C# no se comporta de la misma manera que el siguiente bloque foeach?IEnumerable Select

string [] strs = {"asdf", "asd2", "asdf2"}; 
strs.Select(str => doSomething(str)); 


foreach(string str in strs){ 
    doSomething(str); 
} 

puse un punto de interrupción en el interior de doSomething() y que no se dispara en la Selección, pero lo hace con el foreach.

TIA

+2

Debe leer las primeras palabras de la sección de observaciones en el [Documentación] (http://msdn.microsoft.com/en-us/library/ bb548891.aspx). – ChaosPandion

+0

@ ChaosPandion Tu comentario original fue mucho mejor. ;) – Marc

+0

@Marc - Quería ser un poco más diplomático ya que el OP puede no saber qué significa diferido o ejecución. – ChaosPandion

Respuesta

1

La consulta Linq no será procesada hasta que convierta a un Enumarable usando ToList(), ToArray(), etc.

Y por cierto el equivalente a su estado de cuenta es foreach algo como esto:

strs.ForEach(doSomething);

strs.ToList().ForEach(doSomething); 

o

Array.ForEach(strs, doSomething); 
+0

Supongo que te refieres a Array.ForEach (str, DoSomething) – dharga

+0

@dharga, sí, es correcto, generalmente cometo errores cuando estoy escribiendo código sin probar, la versión correcta sería 'strs.ToList(). ForEach (doSomething); 'o' Array.ForEach (strs, doSomething); ' – fardjad

+0

.Select() es flojo. Además, doSomething() debe devolver un valor, ya que .Select toma a (a -> b), o en .NET speak, toma un Func <..>, no una Acción <..>. – Daniel

10

Esto se debe a que las consultas de LINQ se han aplazado. La lambda pasada al método Select se ejecuta realmente cuando se accede al resultado.

Probar:

string [] strs = {"asdf", "asd2", "asdf2"}; 
var result = strs.Select(str => doSomething(str)); 

foreach(var item in result) { 
} 
+0

lo único que le diría a esto es que prefiero tener una lista estática para iterar en lugar de IEnumerable, si tiene la intención de modificar la colección dentro de su ciclo. – Gent

0

Creo que una vez que utilice los valores devueltos por el selecto verá doSomething() llama. Consulte yield para ver por qué sucede esto.

1

que tendría que hacer algo como

string [] strs = {"asdf", "asd2", "asdf2"}; 
strs = strs.Select(str => doSomething(str)).ToArray(); 


foreach(string str in strs){ 
    doSomething(str); 
}