2011-12-08 12 views
5

pregunta rápida, consulte este código:Foreach con el Método de extensión IEnumerable

List<int> result = new List<int>(); 

var list = new List<int> { 1, 2, 3, 4 }; 

list.Select(value => 
    { 
     result.Add(value);//Does not work?? 
     return value; 
    }); 

Y:

result.Count == 0 //true 

Por qué result.Add (valor) no se ejecuta?

Sin embargo esto no ejecutados, Otra cuestión que es tener una manera de hacer un foreach en un IEnumerable con Extensión Método?

A excepción de esta manera: IEnumerable.ToList().Foreach(p=>...)

+0

necesita hacer un delegado – MethodMan

+1

@DJKRAZE Ya es un delegado. –

+0

Publiqué mi ejemplo de delegado a continuación para utilizar la lista.ParaEach – MethodMan

Respuesta

17

Por qué result.Add (valor) no se ejecuta?

Esto se debe a que LINQ utiliza la ejecución diferida. Hasta que realmente enumere los resultados (el retorno de Select), los delegados no se ejecutarán.

Para demostrarlo, intente lo siguiente:

List<int> result = new List<int>(); 

var list = new List<int> { 1, 2, 3, 4 }; 

var results = list.Select(value => 
    { 
     result.Add(value);//Does not work?? 
     return value; 
    }); 

foreach(var item in results) 
{ 
    // Just iterating through this will cause the above to execute... 
} 

Dicho esto, esta es una mala idea . Las consultas de LINQ no deberían tener efectos secundarios si puede evitarlo. Piense en Select como una forma de transformar sus datos, no ejecutar código.

Sin embargo, esto no se ejecuta, Otra pregunta que es de alguna manera hacer un foreach en un método IEnumerable with Extention?

Se puede escribir su propio método de extensión:

public static void ForEach<T>(this IEnumerable<T> items, Action<T> action) 
{ 
    foreach(var item in items) 
     action(item); 
} 

Sin embargo, yo recomendaría no hacer esto. Para más detalles, consulte Eric Lippert's post on the subject.

+0

Gracias por sus respuestas, su descripción resuelve mi confusión de la comprensión de ejecución IEnumerable y diferida. –

3

Seleccionar es flojo y la ejecución se difiere hasta que comience a enumerar los resultados. Hay que consumir el conjunto de resultados llamando .ToArray por ejemplo, o haciendo un bucle sobre el resultado:

list.Select(value => 
    { 
     result.Add(value);//Does not work?? 
     return value; 
    }).ToArray(); 
+0

Si fuera a usar un método solo para forzar la enumeración, iría a uno con memoria constante como 'Max()' en lugar de 'ToArray()'. –

-1
List<int> result = new List<int>(); 
var list = new List<int> { 1, 2, 3, 4 }; 
list.ForEach(delegate(int sValue) 
{ 
    result.Add(sValue); 
}); 

esto funciona, pero todos y añade 1 2 3 4 en consecuencia. Pruébalo. Lo acabo de hacer.

+0

Mencioné: Excepto de esta manera: IEnumerable.ToList(). Foreach (p => ...) –

Cuestiones relacionadas