只使用扩展方法在Linq中很好,干净的交叉连接

时间:2012-02-02 21:31:09

标签: c# linq join extension-methods

  

可能重复:
  Nested “from” LINQ query expressed with extension methods

我确信以前曾经问过这个问题,但老实说我找不到任何东西。

我很好奇以下仅使用内置Linq扩展方法的等效语法:

var z1 =
    from x in xs
    from y in ys
    select new { x, y };

我可以得到相同的结果:

var z2 = xs.SelectMany(x => ys.Select(y => new { x, y }));

但是它产生了不同的IL代码,而且代码有点复杂且难以理解。使用扩展方法有更简洁的方法吗?


这是我写的完整测试方法:

private void Test()
{
    var xs = new[] { 1D, 2D, 3D };
    var ys = new[] { 4D, 5D, 6D };

    var z1 =
        from x in xs
        from y in ys
        select new { x, y };

    var z2 = xs.SelectMany(x => ys.Select(y => new { x, y }));
}

这是[编辑:C#interp of] IL代码(使用ILSpy):

private void Test()
{
    double[] xs = new double[]
    {
        1.0, 
        2.0, 
        3.0
    };
    double[] ys = new double[]
    {
        4.0, 
        5.0, 
        6.0
    };
    var z =
        from x in xs
        from y in ys
        select new
        {
            x = x,
            y = y
        };
    var z2 = xs.SelectMany((double x) =>
        from y in ys
        select new
        {
            x = x,
            y = y
        });
}

2 个答案:

答案 0 :(得分:37)

一种方法是:

var z2 = xs.SelectMany(x => ys, (x, y) => new {x, y});

答案 1 :(得分:7)

如果您真的想使用单个LINQ扩展方法,那么另一个候选者将是Join,并定义outerKeySelectorinnerKeySelector函数,以便它们始终生成相等的值。

var z3 = xs.Join(ys, x => true, y => true, (x, y) => new { x, y });
但是,这可能会提供比嵌套from解决方案更复杂的IL代码。顺便提一下,MSDN在其示例中使用嵌套的from进行交叉连接;查看How to: Perform Custom Join Operations (C# Programming Guide)中的第一个代码段。