Хорошее, чистое крест-соединение в Linq, используя только методы расширения

Возможный дубликат:
Вложенные "из" запроса LINQ, выраженные с помощью методов расширения

Я уверен, что это было задано раньше, но я честно ничего не мог найти.

Мне любопытно, что эквивалентный синтаксис будет для следующих, используя только встроенные методы расширения 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 }));
}

Здесь [Edit: С# interp] 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
        });
}

Ответы

Ответ 1

Один из способов:

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

Ответ 2

Если вы действительно хотите использовать один метод расширения LINQ, то другим кандидатом будет Join, с outerKeySelector и innerKeySelector, определенные так, что они всегда будут давать равные значения.

var z3 = xs.Join(ys, x => true, y => true, (x, y) => new { x, y });

Это, однако, вероятно, даст более сложный код IL, чем вложенное решение from. Кстати, MSDN использует вложенный пример from в своем примере для перекрестного соединения; посмотрите первый фрагмент кода в Практическое руководство. Выполнение пользовательских операций объединения (Руководство по программированию на С#).