12

免責事項: この質問は、何かを成し遂げるという実際の必要性というよりも、私の個人的な好奇心に突き動かされています。したがって、私の例は不自然になります。それにもかかわらず、それは非常によく発生する可能性がある問題だと思います。

Zipを使用して 2 つのシーケンスを反復処理し、ペアの 1 つのアイテムが他のアイテムと異なることが判明した場合に例外をスローする void メソッドを呼び出すとします (したがって、戻り値は破棄されます)。ここでのポイントは、メソッドが例外をスローすることではなく、void を返すことです。

言い換えれば、私たちはForEach2 つ以上のコレクションを行っているようなものです (ちなみに、私はEric Lippert が何を考えてForEachいるかを知っており、彼に完全に同意し、それを使用することはありません)。

さて、Zipが必要なFunc<TFirst, TSecond, TResult>ので、もちろん に相当するものを渡すことAction<TFirst, TSecond>はできません。

私の質問は次のとおりです:これよりも優れた慣用的な方法はありますか(つまり、ダミー値を返す)?

var collection1 = new List<int>() { ... };
var collection2 = new List<int>() { ... };

collection1.Zip(collection2, (first, second) => 
{
    VoidMethodThatThrows(first, second);
    return true;
});
4

2 に答える 2

22

Zip()アイテムをオブジェクトにスローするために使用し、選択した方法で実行します (悪いToList/ForEach コンボではなく、foreach通常のforeachループを実行してください)。

var items = collection1.Zip(collection2, (x, y) => new { First = x, Second = y });
foreach (var item in items)
{
    VoidMethodThatThrows(item.First, item.Second);
}

C# 7.0 では、タプルのサポートと分解が改善され、作業がはるかに快適になりました。

var items = collection1.Zip(collection2, (x, y) => (x, y));
// or collection1.Zip(collection2, ValueTuple.Create);
foreach (var (first, second) in items)
{
    VoidMethodThatThrows(first, second);
}

さらに、.NET Core と 5 では、値をタプルに自動的にペアにするオーバーロードが追加されるため、そのマッピングを行う必要はありません。

var items = collection1.Zip(collection2); // IEnumerable<(Type1, Type2)>

.NET 6 では、3 番目のコレクションがミックスに追加されます。

var items = collection1.Zip(collection2, collection3); // IEnumerable<(Type1, Type2, Type3)>
于 2012-06-25T13:53:19.377 に答える