Existente método de extensão LINQ semelhante ao Parallel.For? [duplicado]
-
11-07-2019 - |
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++; });
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
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.
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.