簡體   English   中英

將 LINQ 的 Zip 與不返回值的閉包一起使用

[英]Using LINQ's Zip with a closure that doesn't return a value

免責聲明:這個問題是由我個人的好奇心驅動的,而不是完成某事的實際需要。 所以我的例子是人為的。 盡管如此,我認為這是一個很可能會突然出現的問題。

假設我們正在使用Zip迭代兩個序列,調用一個 void 方法,如果發現一對中的一個項目與另一個不同(因此丟棄任何返回值),該方法只會拋出異常。 這里的要點不是該方法拋出異常,而是它返回 void。

換句話說,我們有點像在兩個集合上做一個ForEach (順便說一下,我知道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;
});

使用Zip()將項目放入對象中,然后按照您選擇的方式執行foreach (請執行正常的foreach循環,而不是糟糕的 ToList/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 添加了第三個集合。

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

我經常需要對兩個集合中的每一對執行一個操作 Zip 方法在這種情況下沒有用。

可以使用此擴展方法ForPair

public static void ForPair<TFirst, TSecond>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second,
    Action<TFirst, TSecond> action)
{
    using (var enumFirst = first.GetEnumerator())
    using (var enumSecond = second.GetEnumerator())
    {
        while (enumFirst.MoveNext() && enumSecond.MoveNext())
        {
            action(enumFirst.Current, enumSecond.Current);
        }
    }
}

所以對於你的例子,你可以寫:

var collection1 = new List<int>() { 1, 2 };
var collection2 = new List<int>() { 3, 4 };

collection1.ForPair(collection2, VoidMethodThatThrows);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM