在两个列表中应用运算符的C#-idiomatic方法是什么?

我习惯这样做(从其他语言):

 a = 1, 2, 3;
 b = 5, 1, 2;

 c = a * b;  // c = 5, 2, 6

这需要两个相等大小的列表,并向其成员应用一个函数,一次一个,以获得结果的列表。它可以是一个简单的乘法(上面)或更复杂的函数:

 c = b>a ? b-a : 0;  // c = 4, 0, 0

我可以想到几种不同的方式来做这个在C#,但我不知道如何一个C#训练的程序员会这样做。在C#世界中正确的方法是什么?

(我唯一要问的是c = f(a,b)。我熟悉创建列表和访问他们的元素。)

var c = a.Zip(b, (x, y) => x * y);

对于编辑后更复杂的:

var c = a.Zip(b, (x, y) => x > y ? x - y : 0);

注意,Zip是一个扩展方法from Enumerable that acts on IEnumerable<T>和从Queryable that acts on IQueryable<T>,所以有可能,如果lambda是一个给定的查询提供程序可以处理,它可以被处理为一个SQL查询数据库,或其他方式其他比.NET中的内存。

有人提到这是新的4.0在评论中。这不是很难实现3.5自己:

public class MyExtraLinqyStuff
{
    public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
    {
      //Do null checks immediately;
      if(first == null)
        throw new ArgumentNullException("first");
      if(second == null)
        throw new ArgumentNullException("second");
      if(resultSelector == null)
        throw new ArgumentNullException("resultSelector");
      return DoZip(first, second, resultSelector);
    }
    private static IEnumerable<TResult> DoZip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
    {
      using(var enF = first.GetEnumerator())
      using(var enS = second.GetEnumerator())
        while(enF.MoveNext() && enS.MoveNext())
          yield return resultSelector(enF.Current, enS.Current);
    }
}

对于.NET2.0或.NET3.0,您可以具有相同的,但不是作为扩展方法,它回答了评论中的另一个问题;没有真正的方式在.NET做这样的事情的时候,或者至少没有我们的编程在.NET中的一个坚定的共识。我们中的一些人在我们的工具包中有上面的方法(虽然不是扩展方法),但是更多的是,我们受到其他语言和库的影响比其他任何东西(例如,我正在做类似上面的事情,因为我知道的东西C的STL,但这不是唯一可能的灵感来源)

http://stackoverflow.com/questions/24026624/whats-the-c-idiomatic-way-for-applying-an-operator-across-two-lists

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:在两个列表中应用运算符的C#-idiomatic方法是什么?