2012-04-24 6 views
44

Empecé a incursionar en el metro de Windows 8 recientemente y descubrí que uno de mis viejos amigos parece haber desaparecido.¿Se ha ido el List <T> .ForEach() method?

Tiendo a utilizar el método .ForEach() más de lo que utilizo la construcción tradicional foreach(), y me di cuenta rápidamente de que este método no está disponible. Por ejemplo, este código no compila con la aplicación de un metro de:

var list = new List<string>(); 

list.ForEach(System.Diagnostics.Debug.WriteLine); 

He buscado para ver si podía encontrar cualquier discusión sobre esto, pero no era capaz de hacerlo. ¿Estoy siendo obtuso, o se ha ido realmente?

+3

IEnumerable nunca tuvo un método de extensión ForEach solo IList lo tiene – Clueless

+0

Usted señor, está en lo cierto. Fui prematuramente genérico. Cambiaré el título de la pregunta. – Robaticus

+0

Cometí el mismo error: el título dice IEnumerable, pero el ejemplo claramente lo intenta en una lista. Editar: Título actualizado :-) – yamen

Respuesta

42

It's indeed gone:

Lista <T> .ForEach se ha eliminado en las aplicaciones estilo Metro. Si bien el método parece simple, tiene una serie de problemas potenciales cuando la lista se transforma por el método pasado a ForEach. En su lugar, se recomienda que simplemente use un ciclo foreach.


Wes Haggard | .NET Framework Team (BCL) | http://blogs.msdn.com/b/bclteam/

muy extraña, sin embargo, se hace una aparición en la documentation, en la que en ninguna parte se declara que este método no es compatible con .NET para aplicaciones Windows Store (antes de .NET para aplicaciones de estilo Metro) . Quizás esto es solo un descuido de parte del equipo de documentación.

+1

@Robaticus: simplemente puede agregar su propio método de extensión para reemplazarlo. Probablemente sea mejor llamar '.ToList()' primero, luego iterar eso. No hay nada como iterar una fuente mientras intentas mutarla para arruinar tu día. – Will

+1

@Will - Estoy de acuerdo en que podría hacerlo. Sin embargo, es un buen hábito para salir, especialmente cuando se muestra a los nuevos programadores LINQ cómo hacer las cosas. – Robaticus

16

Una alternativa es definir por sí mismo, por supuesto:

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action) 
{ 
    foreach(T item in enumeration) 
    { 
     action(item); 
     yield return item; 
    } 
} 

Crédito: LINQ equivalent of foreach for IEnumerable<T>

(Nota: no es un duplicado)

+2

Aunque esta es definitivamente una práctica aceptable, solo tenga cuidado de que no modifique ningún requisito de llamadas IEnumerable previas (como Where o OrderBy). Además, si desea continuar encadenando las llamadas IEnumerable, puede cambiar el tipo de devolución a 'IEnumerable ' y 'yield return item' después de realizar la acción en el elemento. Sin embargo, esto aún mutará los elementos, así que tenga en cuenta que estos "efectos secundarios" podrían alterar la enumeración. – SPFiredrake

+0

Sí, ForEach es ciertamente peligroso. Actualicé la respuesta para devolver 'IEnumerable ' para permitir el encadenamiento continuo, pero es probable que esto haga las cosas más peligrosas. – yamen

18

Para tener una idea de por qué ya no podría ser incluido, lea esta publicación de alguien que trabaja en el equipo de C# en Microsoft: http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

Básicamente, es filosofía. Las características "LINQ" están altamente inspiradas en el paradigma de programación funcional, y la extensión ForEach va en contra de eso ... alienta un estilo funcional pobre.

+0

Joel: me hice prematuramente genérico y cambié el título para reflejar la lista , en lugar de IEnumerable . – Robaticus

+8

"alguien que trabaja en el equipo de C# en Microsoft" Qué sutil ... – BoltClock

+9

Ahhh, es solo ese tipo Lippert otra vez. ¿Qué diablos sabe él? ;) – Robaticus

Cuestiones relacionadas