¿Por qué no existe ningún método de extensión ForEach en IEnumerable?

Resuelto Cameron MacFarland asked hace 15 años • 21 respuestas

Inspirado en otra pregunta sobre la Zipfunción que falta:

¿ Por qué no hay ningún ForEachmétodo de extensión en la IEnumerableinterfaz? ¿O en cualquier lugar? La única clase que obtiene un ForEachmétodo es List<>. ¿Hay alguna razón por la que falta, tal vez el rendimiento?

Cameron MacFarland avatar Sep 19 '08 18:09 Cameron MacFarland
Aceptado

Ya existe una foreachdeclaración incluida en el lenguaje que hace el trabajo la mayor parte del tiempo.

Odiaría ver lo siguiente:

list.ForEach( item =>
{
    item.DoSomething();
} );

En lugar de:

foreach(Item item in list)
{
     item.DoSomething();
}

Este último es más claro y fácil de leer en la mayoría de situaciones , aunque quizás sea un poco más largo de escribir.

Sin embargo, debo admitir que cambié mi postura sobre ese tema; De hecho, un ForEach()método de extensión sería útil en algunas situaciones.

Estas son las principales diferencias entre la declaración y el método:

  • Comprobación de tipos: foreach se realiza en tiempo de ejecución, ForEach()en tiempo de compilación (¡Gran ventaja!)
  • La sintaxis para llamar a un delegado es mucho más simple: objetos.ForEach(DoSomething);
  • ForEach() podría encadenarse: aunque la maldad/utilidad de tal característica está abierta a discusión.

Todos esos son grandes puntos planteados por mucha gente aquí y puedo ver por qué a la gente le falta la función. No me importaría que Microsoft agregue un método ForEach estándar en la próxima iteración del marco.

Coincoin avatar Sep 19 '2008 12:09 Coincoin

El método ForEach se agregó antes de LINQ. Si agrega la extensión ForEach, nunca se llamará para instancias de Lista debido a restricciones de los métodos de extensión. Creo que la razón por la que no se agregó es para no interferir con el existente.

Sin embargo, si realmente echas de menos esta pequeña función, puedes implementar tu propia versión.

public static void ForEach<T>(
    this IEnumerable<T> source,
    Action<T> action)
{
    foreach (T element in source) 
        action(element);
}
aku avatar Sep 19 '2008 11:09 aku