2012-02-02 12 views

答えて

39

このフォームのすべての質問には、C#仕様の7.16節で回答します。

あなたの具体的な質問は、この段落で回答されています


select

from x1 in e1 
from x2 in e2 
select v 

続く第二from句を指定したクエリ式が

(e1) . SelectMany(x1 => e2 , (x1 , x2) => v) 

に翻訳されます

だからあなたのクエリ:

var query = from a in sequenceA    
      from b in sequenceB 
      select ...; 

var query = (sequenceA) . SelectMany(a => sequenceB , (a , b) => ...) 

と同じですが(これは「...」という表現で、そして、言う、表現が続いていないことを前提として当然のことに注意してください

HDVの答えは指摘クエリ継続で。)その

var query = (sequenceA) . SelectMany( 
    a => (sequenceB) . Select(b => ...)); 

でも論理的に有効な翻訳になりますが、実際に実行する翻訳ではありません。 LINQ実装の初期段階では、これが私たちが選んだ翻訳でした。しかし、より多くのファイルをfrom節に積み重ねると、ラムダネストがますます深くなり、という膨大な型推論の問題がコンパイラに表示されます。この変換の選択はコンパイラのパフォーマンスを低下させるので、深く入れ子にされたスコープのseamnticsを表すより安価な方法を与えるために透過識別子メカニズムを導入しました。これらの被験者の興味

をした場合:深くネストラムダが解決するコンパイラのための困難な問題を提示する理由の詳細な思考のために

は、以下を参照してください。詳しくは

http://blogs.msdn.com/b/ericlippert/archive/2007/03/26/lambda-expressions-vs-anonymous-methods-part-four.aspx

http://blogs.msdn.com/b/ericlippert/archive/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five.aspx

透過的な識別子に関する情報は、Wes DyerのC#3で実装されたこの記事を参照してください。0:

http://blogs.msdn.com/b/wesdyer/archive/2006/12/22/transparent-identifiers.aspx

そして、それらについての記事の私のシリーズ:

http://ericlippert.com/2014/07/31/transparent-identifiers-part-one/

+3

"C#言語仕様"はダウンロード可能なWord文書であるため、ほとんどの検索エンジンでは索引付けされず、オンラインでは読み込みできません。多分、マイクロソフトはそれを将来変更する可能性があります! –

9
var query = sequenceA.SelectMany(a => sequenceB.Select(b => ...)); 

編集:コメントでエリックリペットで指摘したように、これは、同じ結果が得られますが、それは内部的に変換されるか、意図的ではありません。彼の答えは、SelectManyに電話する別の方法を参照してください。これはオリジナルに対応しています。また、わかりやすくするために省略したb =>を追加しました。

+0

う 'VARのような非ネストされた変種query = sequenceA.SelectMany(a => sequenceB).Select(...); 'も動作しますか? –

+0

@ OlivierJacot-Descombesこれも可能ですが、2番目の 'Select'のパラメータから' a'を参照することはできません。 – hvd

+0

@hdv:あなたのどちらも正しいわけではありません。 Olivierのコメントでは、範囲変数「a」を失っていることを指摘するのは間違いありません。しかし、両方の翻訳では、両方とも範囲変数 'b'を失ってしまいました。 「b」はあなたの翻訳にどこに行きましたか? '...'が 'b'を指すとどうなるでしょうか?どこか別のラムダが必要です! –

1

書くための別の方法は、それは次のようになります。

var query = a.Join(b, i => new { }, j => new { }, (i, j) => new { i = i, j = j }); 
+0

ネストされた 'from'ステートメントと' SelectMany'は両方ともネストされた列挙を平坦化します。私。列挙体の列挙体を、ソースの入れ子になった列挙体のすべての要素を含む1つのフラットな列挙体に変換します。彼らは無関係な2つの列挙に参加しません。 –

+0

私がやったのは、あなたがリストした他のオプションと同じクロスジョインです。結果列挙もフラットです。それを試してみてください:)。 –

+0

例:文字列[] []入れ子=新しい文字列[] [] { \t新しい文字列[] {"a"、 "b"、 "c"}、 \t新しい文字列[] {"AA"新しい文字列[] {"1"、 "2"、 "3"}、 }; '、" CC "期待される出力:「a」「b」「c」「AA」「BB」「CC」「DD」「1」「2」「3」 –

関連する問題