2012-02-02 14 views
14
を使用してLINQの中で参加

可能性の重複:
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コードを生成し、コードはちょっと複雑で分かりにくいです。拡張メソッドでこれを行うためのよりクリーンな方法がありますか?


は、ここに書かれたとして私の全体のテスト方法です:(ILSpyを使用して)ILコード:[のC#のinterpの編集]:

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 })); 
} 

はここだ

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 
     }); 
} 
+7

ええと、これはilコードではありませんか? –

+1

これは、ILではなく逆アセンブリからのC#解釈のようです。 –

+4

Eric Lippertは今日ここで同じ質問に答えています:http://stackoverflow.com/questions/9115675/nested-from-linq-query-expressed-with-extension-methods/9117009#9117009 – hvd

答えて

33

一つの方法は次のようになります:

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

+1:これはおそらく最良の解決策です。 – Douglas

+1

@マグヌス、これです、+1、ありがとう。私はあなたにそれをさせる 'SelectMany'のオーバーロードがあったことを認識しませんでした。上記の@ Danielのコメントのおかげで、ILSpyのクエリ構文ではなく、拡張メソッドのバージョンを見ることができ、基本的にあなたの答えが出てきたことを知りました。 – devuxer

6

単一のLINQ拡張メソッドを使用すると、別の候補がouterKeySelectorinnerKeySelector関数が常に等しい値を生成するように定義されたJoinになります。

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)の最初のコードスニペットを見てください。