2017-05-24 16 views
4

これらの2つのクエリの結果の型が異なる理由は誰にも分かりますか? Q2はIOrderedEnumerable<int>ない理由orderby句を使用したlinqクエリの一貫性のない戻り値タイプ

// q1 is IOrderedEnumerable<int> 
var q1 = from c1 in new[] { 1, 2, 3 } 
     orderby c1 
     select c1; 

// q2 is IEnumerable<int> 
var q2 = from c1 in new[] { 1, 2, 3 } 
     from c2 in new[] { 1, 2, 3 } 
     where c1 == c2 
     orderby c1 
     select c1; 

私はうまくできません。

Q1:OrderedEnumerable<int, int>

Q2実際のタイプがある(宣言インタフェースがあることではなく)返さ今

// q3 is IEnumerable<int> 
var q3 = from c1 in new[] { 1, 2, 3 } 
     join c2 in new[] { 1, 2, 3 } 
     on c1 equals c2 
     orderby c1 
     select c1; 

答えて

5

最初のクエリでは、実行中の実際のSelectは存在しません。 selectはシーケンス内の現在の項目を選択していますが、これはno opなので、Selectコールは単に省略されます。 Selectコールが省略されている場合は、OrderByがクエリの最後の呼び出しであり、IOrderedEnumerable<T>を返します。

2番目(および3番目)のクエリの場合、selectは実際に意味のあるものを選択しているため省略できません。 (2番目のクエリでは、SelectManyIEnumerableの匿名型を返すので、3番目のクエリではとなります)。したがって、Selectは依然としてクエリにあり、SelectIEnumerable<T>を返します。

お問合せがに翻訳されているものを見たときには、以下の道徳的等価になる、十分に簡単です:これらはあなたのクエリは同等である、それは明確にどうあるべきかであることを考えると

var q1a = new[] { 1, 2, 3 }.OrderBy(c1 => c1); 

var q2a = new[] { 1, 2, 3 }.SelectMany(c1 => new[] { 1, 2, 3 }.Select(c2 => new { c1, c2 })) 
    .Where(variables => variables.c1 == variables.c2) 
    .OrderBy(variables => variables.c1) 
    .Select(variables => variables.c1); 

var q3a = new[] { 1, 2, 3 }.Join(new[] { 1, 2, 3 }, c1 => c1, c2 => c2, (c1, c2) => new { c1, c2 }) 
    .OrderBy(variables => variables.c1) 
    .Select(variables => variables.c1); 

なぜ最初のものだけがIOrderedEnumerable<int>を返しますか?

+0

q2のSelectManyの仕組みを明確にすることはできますか? –

+0

素敵な説明!ありがとうございました! –

-3

:句は違いはありません '参加' 使用

Enumerable+WhereSelectEnumerableIterator<AnonymousType<int, int>, int>

(q3はq2と同じ)

+0

質問は、変数の*コンパイル時のタイプを指定することです。あなたはまた、なぜタイプが異なるのかの質問に答えていません。 – Servy

+0

これはなぜ彼らが異なるのかについての質問には答えません –

関連する問題