programming parallel net for examples example c# linq extension-methods iteration

c# - for - parallel vb net



¿Existe un método de extensión LINQ similar a Parallel.For? (4)

Posible duplicado:
El equivalente LINQ de foreach para IEnumerable <T>

Los métodos de extensión linq para ienumerable son muy útiles ... pero no son tan útiles si lo único que quieres hacer es aplicar algunos cálculos a cada elemento en la enumeración sin devolver nada. Así que me preguntaba si tal vez me estaba perdiendo el método correcto, o si realmente no existe, ya que prefiero usar una versión incorporada si está disponible ... pero no he encontrado uno :-)

Podría haber jurado que había un método .ForEach en alguna parte, pero aún no lo he encontrado. Mientras tanto, escribí mi propia versión en caso de que sea útil para cualquier otra persona:

using System.Collections; using System.Collections.Generic; public delegate void Function<T>(T item); public delegate void Function(object item); public static class EnumerableExtensions { public static void For(this IEnumerable enumerable, Function func) { foreach (object item in enumerable) { func(item); } } public static void For<T>(this IEnumerable<T> enumerable, Function<T> func) { foreach (T item in enumerable) { func(item); } } }

el uso es:

myEnumerable.For<MyClass>(delegate(MyClass item) { item.Count++; });


Arrojando un poco más de luz sobre por qué:

LINQ es funcional en la naturaleza. Se usa para consultar datos y devolver resultados. Una consulta LINQ no debe alterar el estado de la aplicación (con algunas excepciones como el almacenamiento en caché). Debido a que foreach no arroja ningún resultado, no tiene muchos usos que no impliquen alterar el estado de algo además de lo que le está pasando. Y si necesita un método de extensión Foreach (), es fácil ejecutar el suyo propio.

Si, por otro lado, lo que desea es tomar una entrada y llamar a una función en cada elemento que devuelve un resultado, LINQ proporciona un camino a través de su método de selección.

Por ejemplo, el siguiente código llama a una función delegada en cada elemento de una lista, y devuelve verdadero si ese elemento es positivo:

static void Main(string[] args) { IEnumerable<int> list = new List<int>() { -5, 3, -2, 1, 2, -7 }; IEnumerable<bool> isPositiveList = list.Select<int, bool>(i => i > 0); foreach (bool isPositive in isPositiveList) { Console.WriteLine(isPositive); } Console.ReadKey(); }


El método ForEach en List<T> hace esto. Puede envolver su colección en una lista y luego usar esa llamada, pero eso no es realmente algo bueno que hacer. Parece que tendrás que hacer tu propio.


En realidad, el marco de Extensiones reactivas de Microsoft Research agregó esta funcionalidad. En el ensamblado System.Interactive han incluido extensiones Run() y Do() para IEnumerable<T> .

Do (acción) ejecutará la acción en cada elemento y lo devolverá. Esto es útil para agregar el registro a una consulta de linq, por ejemplo:

var res = GetRandomNumbers(100).Take(10) .Do(x => Console.WriteLine("Source -> {0}", x)) .Where(x => x % 2 == 0) .Do(x => Console.WriteLine("Where -> {0}", x)) .OrderBy(x => x) .Do(x => Console.WriteLine("OrderBy -> {0}", x)) .Select(x => x + 1) .Do(x => Console.WriteLine("Select -> {0}", x));

Esto dará como resultado:

Source -> 96 Where -> 96 Source -> 25 Source -> 8 Where -> 8 Source -> 79 Source -> 25 Source -> 3 Source -> 36 Where -> 36 Source -> 51 Source -> 53 Source -> 81 OrderBy -> 8 Select -> 9 9 OrderBy -> 36 Select -> 37 37 OrderBy -> 96 Select -> 97 97

Run (acción) es como un bucle foreach, lo que significa que está doblando la secuencia que ejecuta la acción.

Puedes leer más sobre esto aquí: http://community.bartdesmet.net/blogs/bart/archive/2009/12/26/more-linq-with-system-interactive-the-ultimate-imperative.aspx

El marco de Rx se puede encontrar aquí: http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx


Ya discutido aquí y allá .

Estoy demasiado soñoliento para recordar, pero, básicamente, un método .ForEach en una aplicación de un solo hilo es funcionalmente equivalente a la declaración foreach ya existente. Por lo que entiendo, la principal diferencia es que se podría paralizar un ForEach, pero eso introduciría comportamientos no deseados con demasiada facilidad.