Pergunta

Duplicate possíveis:
LINQ equivalente a foreach para IEnumerable

Os métodos de extensão LINQ para IEnumerable são muito úteis ... mas não tão útil se tudo que você quer fazer é aplicar um pouco de computação para cada item na enumeração sem devolver nada. Então eu queria saber se talvez eu só estava faltando o método certo, ou se ele realmente não existe como eu prefiro usar um built-in versão se ele está disponível ... mas eu não encontrei um: -)

Eu poderia jurar que havia um método .ForEach algum lugar, mas eu ainda tenho que encontrá-lo. Nesse meio tempo, eu escrevi a minha própria versão no caso, é útil para ninguém:

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);
        }
    }
}

uso é:

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

Foi útil?

Solução

Derramamento um pouco mais de luz sobre por que:

LINQ é funcional na natureza. Ele é usado para consultar os resultados dos dados e retorno. Uma consulta LINQ não deve ser alterando o estado da aplicação (com algumas exceções, como caching). Porque foreach não retorna qualquer resultado, ele não tem muitos usos que não envolvem alterar o estado de algo além do que você está passando para ele. E se você precisar a) método de extensão foreach (, ele é fácil de rolar o seu próprio.

Se, por outro lado, o que você quer é tomar entrada e chamar uma função em cada item que retorna um resultado, LINQ fornece um caminho através de seu método de seleção.

Por exemplo, o código a seguir chama um delegado função em cada item em uma lista, retornando true se esse item é 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();        
    }

Outras dicas

Na verdade, o quadro Reactive Extensions da Microsoft Research fez adicionar esta funcionalidade. No System.Interactive montagem eles incluíram uma Run() e um Do() extensões para IEnumerable<T>.

Do (ação) irá executar a ação em cada elemento e deu-lo de volta. Isso é útil para adicionar o registo a uma consulta linq por exemplo:

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));

Isto irá resultar em:

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

Executar (acção) é como um loop foreach, o que significa que a sua dobragem a sequência que a execução da acção.

Você pode ler mais sobre ele aqui: http://community.bartdesmet.net/blogs/bart/archive/2009/12/26/more-linq-with-system-interactive-the-ultimate-imperative. aspx

O quadro Rx pode ser encontrada aqui: http://msdn.microsoft. com / en-us / DevLabs / ee794896.aspx

O método ForEach em List<T> faz isso. Você poderia envolver sua coleção em uma lista e, em seguida, usar essa chamada, mas isso não é realmente uma coisa boa para fazer. Parece que você vai ter que rolar o seu próprio.

Já discutido aqui e .

Im muito sonolento de lembrar, mas, basicamente, um método .ForEach em uma única aplicação fio é funcionalmente equivalente a declaração foreach já existente. Pelo que eu entendo, a principal diferença é que um ForEach poderia ser parallized mas que iria introduzir comportamentos indesejados com muita facilidade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top