2009-05-13 22 views
47

Duplicar posible:
Why is there not a ForEach extension method on the IEnumerable interface?expresión lambda utilizando Foreach Cláusula

EDITAR

Como referencia, aquí está la entrada del blog, que Eric referrrred en los comentarios

http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

ORIG

Más de una curiosidad, pero supongo que uno de los savants C# Especificación ...

Por qué es que la cláusula ParaCada() no funciona (o no es disponible) para su uso en conjuntos de resultados IQueryable/IEnumerable ...

Primero tiene que convertir los resultados ToList() o ToArray() Presumiblemente hay una limitación técnica en la forma en que C# itera IEnumerables vs. Listas ... Tiene algo que ver con Ejecución diferida de IEnumerables/IQuerable Collections. p.

var userAgentStrings = uasdc.UserAgentStrings 
    .Where<UserAgentString>(p => p.DeviceID == 0 && 
          !p.UserAgentString1.Contains("msie")); 
//WORKS    
userAgentStrings.ToList().ForEach(uas => ProcessUserAgentString(uas));   

//WORKS 
Array.ForEach(userAgentStrings.ToArray(), uas => ProcessUserAgentString(uas)); 

//Doesn't WORK 
userAgentStrings.ForEach(uas => ProcessUserAgentString(uas)); 
+4

Escribiría 'ForEach (uac => ProcessUserAgentString (uas))' como 'ForEach (ProcessUserAgentString)'. –

+1

¿Cuál es el problema con un bucle for-each convencional? foreach (var uas en UserAgentStrings) ProcessUserAgentString (uas); – Dario

+0

No hay problema ...Como dije, era más una curiosidad que la convención estuviera disponible para usar en Arrays/Lists pero no en IQueryables/IEnumerables y como Eric Lippert señaló a continuación, es una elección completamente filosófica del equipo de desarrollo y no por ningún motivo técnico –

Respuesta

55

Lo que una coincidencia asombrosa, sólo escribía ahora un artículo de blog sobre esta misma pregunta. Es será was published May 18th. No hay ninguna razón técnica por la que nosotros (¡o usted!) No podamos hacer esto. Las razones por las cuales no son filosóficas. Ver mi blog la próxima semana para mi argumento.

+1

No entiendo por qué no crees que es útil cuando encadenas muchos métodos como. Donde (...). Selecciona (...). Para cada uno (...); – Micah

+5

@Micah: ¿Qué razón di en mi artículo no estaba claro? Yo sí creo que es útil. Creo que es * insuficientemente útil * para justificar el trabajo y que fomenta malas prácticas de codificación, como la incorporación de efectos secundarios en lo que lógicamente parecen consultas. Cualquiera de las dos razones es suficiente para no agregar este método. –

+0

@EricLippert ¿Por qué se ha agregado después de todo? –

13

Es perfectamente posible escribir un método de extensión para ForEachIEnumerable<T>.

No estoy realmente seguro de por qué no se incluye como un método de extensión incorporada:

  • ForEach Tal vez porque ya existía en List<T> y Array antes de LINQ.
  • Quizás porque es bastante fácil usar un bucle foreach para iterar la secuencia.
  • Quizás porque no se sentía funcional/LINQy suficiente.
  • Tal vez porque no se puede encadenar. (Es bastante fácil de hacer una versión chainable que yield s cada artículo después de realizar una acción, pero que el comportamiento no es particularmente intuitiva.)

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) 
{ 
    if (source == null) throw new ArgumentNullException("source"); 
    if (action == null) throw new ArgumentNullException("action"); 

    foreach (T item in source) 
    { 
     action(item); 
    } 
} 
+0

punto tomado, pero la pregunta era más en referencia a por qué no está disponible de fábrica ... es decir, Array tiene un método estático 'ForEach()'. La lista tiene una ... ¿Por qué no IEnumerable/IQueryable? –

+0

Supongo que tendremos que esperar la publicación del blog de Eric para descubrir la respuesta real;) – LukeH

+0

Tus conjeturas son notablemente similares a mi publicación. –

Cuestiones relacionadas