Pregunta

Posibles Duplicados:
LINQ equivalente de un foreach para IEnumerable<T>

Los métodos de extensión de linq para ienumerable son muy útiles ...pero no que útil si lo que quieres hacer es aplicar un poco de cálculo de cada elemento de la enumeración sin devolver nada.Así que me preguntaba si tal vez yo estaba solo falta que el método correcto, o si en realidad no existe como prefiero usar una versión integrada si es disponible ...pero no he encontrado uno :-)

Yo podría haber jurado que había una .Método ForEach en algún lugar, pero todavía tengo que encontrar.En el ínterin, me hizo escribir 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++; });

¿Fue útil?

Solución

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

LINQ es funcional por naturaleza. Se utiliza para consultar datos y devolver resultados. Una consulta LINQ no debería alterar el estado de la aplicación (con algunas excepciones como el almacenamiento en caché). Debido a que foreach no devuelve 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 de implementar el suyo.

Si, por otro lado, lo que desea es ingresar información 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 un delegado de función en cada elemento de una lista, devolviendo 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();        
    }

Otros consejos

En realidad, el Reactivo Extensiones marco de Investigación de Microsoft hizo agregar esta funcionalidad.En el System.Interactive la asamblea se ha incluido un Run() y un Do() extensiones IEnumerable<T>.

Hacer(acción) se ejecutará la acción en cada elemento y el rendimiento de vuelta.Esto es útil para agregar el registro a una consulta 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 resultará en:

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

De ejecución(acción) es como un bucle foreach, lo que significa que su plegamiento de la secuencia que la ejecución de la acción.

Usted puede 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

La Rx marco se pueden encontrar aquí: http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx

El método ForEach en List<T> hace esto. Podría incluir su colección en una lista y luego usar esa llamada, pero eso no es realmente algo agradable. Parece que tendrás que rodar el tuyo.

Ya discutido aquí y allí .

Estoy demasiado somnoliento para recordarlo, 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 un ForEach podría paralizarse, pero eso introduciría comportamientos no deseados con demasiada facilidad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top