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

dev*_*xer 16 c# linq extension-methods join

可能重复:
使用扩展方法表示的嵌套"来自"LINQ查询

我确定以前曾经问过,但老实说我找不到任何东西.

我很好奇只使用内置的Linq扩展方法,以下内容的等效语法是什么:

var z1 =
    from x in xs
    from y in ys
    select new { x, y };
Run Code Online (Sandbox Code Playgroud)

我可以得到相同的结果:

var z2 = xs.SelectMany(x => ys.Select(y => new { x, y }));
Run Code Online (Sandbox Code Playgroud)

但它产生不同的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 }));
}
Run Code Online (Sandbox Code Playgroud)

这是[编辑: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
        });
}
Run Code Online (Sandbox Code Playgroud)

Mag*_*nus 38

一种方法是:

var z2 = xs.SelectMany(x => ys, (x, y) => new {x, y});
Run Code Online (Sandbox Code Playgroud)

  • @Magnus,这就是它,+1并谢谢.我没有意识到"SelectMany"的超载会让你这么做.由于@ Daniel上面的评论,我还了解到我可以查看扩展方法版本而不是ILSpy中的查询语法,它基本上是你的答案. (2认同)

Dou*_*las 7

如果你真的想用一个单一的LINQ扩展方法,然后另一位候选人会Join,与outerKeySelectorinnerKeySelector定义,使得它们总是会产生相等值的函数.

var z3 = xs.Join(ys, x => true, y => true, (x, y) => new { x, y });
Run Code Online (Sandbox Code Playgroud)

但是,这可能会提供比嵌套from解决方案更复杂的IL代码.顺便提一下,MSDN from在其示例中使用嵌套来进行交叉连接; 请参阅如何:执行自定义连接操作(C#编程指南)中的第一个代码段.