Aplicar función a todos los elementos de colección a través de LINQ

Recientemente comencé con LINQ y es increíble. Me preguntaba si LINQ me permitiría aplicar una función, cualquier función, a todos los elementos de una colección, sin utilizar foreach. Algo así como las funciones python lambda.

Por ejemplo, si tengo una lista int, ¿puedo agregar una constante a cada elemento con LINQ?

Si tengo una tabla DB, ¿puedo establecer un campo para todos los registros usando LINQ?

Estoy usando C #

Una forma común de abordar esto es agregar su propio método genérico IEnumerable en IEnumerable . Aquí está el que tenemos en MoreLINQ :

 public static void ForEach(this IEnumerable source, Action action) { source.ThrowIfNull("source"); action.ThrowIfNull("action"); foreach (T element in source) { action(element); } } 

(Donde ThrowIfNull es un método de extensión en cualquier tipo de referencia, que hace lo obvio).

Será interesante ver si esto es parte de .NET 4.0. Va en contra del estilo funcional de LINQ, pero no hay duda de que muchas personas lo encuentran útil.

Una vez que lo tienes, puedes escribir cosas como:

 people.Where(person => person.Age < 21) .ForEach(person => person.EjectFromBar()); 

La forma idiomática de hacer esto con LINQ es procesar la colección y devolver una nueva colección asignada de la manera que desee. Por ejemplo, para agregar una constante a cada elemento, querrías algo como

 var newNumbers = oldNumbers.Select(i => i + 8); 

Hacer esto de una manera funcional en lugar de mutar el estado de su colección existente con frecuencia lo ayuda a separar distintas operaciones de una manera que es más fácil de leer y más fácil de entender para el comstackdor.

Si se encuentra en una situación en la que realmente desea aplicar una acción a cada elemento de una colección (una acción con efectos secundarios que no están relacionados con el contenido real de la colección) eso no es realmente lo que LINQ es más adecuado, aunque podría falsificarlo con Select (o escribir su propio método de extensión IEnumerable , como lo han hecho muchas personas). Probablemente sea mejor seguir con un ciclo foreach en ese caso.

También podría considerar ir en paralelo, especialmente si no le importa la secuencia y más acerca de cómo hacer algo por cada elemento:

 SomeIEnumerable.AsParallel().ForAll( Action / Delegate / Lambda ) 

Por ejemplo:

 var numbers = new[] { 1, 2, 3, 4, 5 }; numbers.AsParallel().ForAll( Console.WriteLine ); 

HTH.

jaja, amigo, acabo de hacer esta pregunta hace unas horas (más o menos) … prueba esto:

ejemplo:

 someIntList.ForEach(i=>i+5); 

ForEach() es uno de los métodos integrados de .NET

Esto modificará la lista, en lugar de devolver una nueva.

O puedes hackearlo.

 Items.All(p => { p.IsAwesome = true; return true; }); 

Para colecciones que no son compatibles con ForEach , puede usar el método ForEach estático en la clase Parallel :

 var options = new ParallelOptions() { MaxDegreeOfParallelism = 1 }; Parallel.ForEach(_your_collection_, options, x => x._Your_Method_()); 

Puedes intentar algo como

 var foo = (from fooItems in context.footable select fooItems.fooID + 1); 

Devuelve una lista de id +1, puede hacer lo mismo con el uso de una función para lo que tenga en la cláusula de selección.

Actualización: Tal como lo sugirió Jon Skeet, esta es una mejor versión del fragmento de código que acabo de publicar:

 var foo = context.footable.Select(foo => foo.fooID + 1); 

Encontré alguna manera de realizar en el diccionario contener mis métodos de clase personalizados

 foreach (var item in this.Values.Where(p => p.IsActive == false)) item.Refresh(); 

De donde ‘esto’ deriva de: Dictionary

 class MyCustomClass { public void Refresh(){} }