Parallel.Forに似た既存のLINQ拡張メソッド? [複製]
-
11-07-2019 - |
質問
ienumerableのlinq拡張メソッドは非常に便利です...しかし、何も返さずに列挙内の各項目に何らかの計算を適用するだけであれば、それほど便利ではありません。だから私はおそらく正しい方法を逃していたのか、それが利用可能であれば組み込みバージョンを使用したいので本当に存在しないのではないかと思っていました...しかし、私は1つを見つけていません:-)
.ForEachメソッドがどこかにあると誓ったかもしれませんが、まだ見つけていません。それまでは、他の人に役立つ場合に備えて独自のバージョンを作成しました。
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);
}
}
}
使用方法:
myEnumerable.For<MyClass>(delegate(MyClass item) { item.Count++; });
解決
理由をもう少し詳しく説明します:
LINQは本来機能的です。データを照会し、結果を返すために使用されます。 LINQクエリは、アプリケーションの状態を変更するものであってはなりません(キャッシングなどの例外はあります)。 foreachは結果を返さないため、渡すもの以外の状態を変更することを伴わない多くの用途はありません。また、Foreach()拡張メソッドが必要な場合は、 独自のメソッドを簡単に作成できます。
一方で、入力を取得し、結果を返す各アイテムで関数を呼び出す場合、LINQはselectメソッドを介して方法を提供します。
たとえば、次のコードはリスト内のすべてのアイテムで関数デリゲートを呼び出し、そのアイテムが正の場合にtrueを返します。
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();
}
他のヒント
実際には、Microsoft ResearchのReactive Extensionsフレームワークがこの機能を追加しました。
System.Interactive
アセンブリには、Run()
へのDo()
およびIEnumerable<T>
拡張が含まれています。
Do(action)は各要素でアクションを実行し、それを返します。これは、たとえばlinqクエリにロギングを追加するのに便利です。
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));
結果は次のとおりです。
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(action)はforeachループのようなもので、アクションを実行するシーケンスを折り畳むことを意味します。
ここで詳細を読むことができます: http://community.bartdesmet.net/blogs/bart/archive/2009/12/26/more-linq-with-system-interactive-the-ultimate-imperative。 aspx
Rxフレームワークは、 http://msdn.microsoftにあります。 com / en-us / devlabs / ee794896.aspx
List<T>
のForEachメソッドがこれを行います。コレクションをリストにラップしてからその呼び出しを使用することもできますが、それは本当に良いことではありません。独自にロールする必要があるようです。