带有orderby子句的linq查询的返回类型不一致

Spo*_*man 4 c# 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;
Run Code Online (Sandbox Code Playgroud)

我不明白为什么Q2是不是也是一个IOrderedEnumerable<int>.

使用'join'子句没有区别:

// 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;
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 5

在第一个查询中,没有Select执行实际操作.所述select被选择的顺序,这是一个无操作中的当前项,因此Select呼叫被简单地省略.随着Select呼叫省略,则OrderBy是在查询中的最后一次通话,并返回一个IOrderedEnumerable<T>.

对于第二个(和第三个)查询,select实际上是选择了有意义的东西,并且不能省略.(在第二个查询中,SelectMany将返回一个IEnumerable匿名类型,就像Join在第三个查询中一样.)因此在这些情况下Select,查询中仍然存在,并Select返回IEnumerable<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);
Run Code Online (Sandbox Code Playgroud)

鉴于这些是您的查询等同于什么,应该清楚为什么只有第一个返回一个IOrderedEnumerable<int>.