嵌套"来自"LINQ查询用扩展方法表示

Oli*_*bes 26 c# linq

如何使用扩展方法语法编写此LINQ查询?

var query = from a in sequenceA
            from b in sequenceB
            select ...; 
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 46

为了您将来的参考,本表格中的所有问题均由C#规范的第7.16节回答.

本段回答您的具体问题:


带有第二个from子句后跟select子句的查询表达式

from x1 in e1
from x2 in e2
select v
Run Code Online (Sandbox Code Playgroud)

被翻译成

( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )
Run Code Online (Sandbox Code Playgroud)

所以你的查询:

var query = from a in sequenceA            
            from b in sequenceB
            select ...;  
Run Code Online (Sandbox Code Playgroud)

是相同的

var query =  ( sequenceA ) . SelectMany( a => sequenceB , ( a , b ) => ... )
Run Code Online (Sandbox Code Playgroud)

(注意,当然这假设"..."是表达式,而不是表示后跟查询延续的表达式.)

hdv的答案指出了这一点

var query =  ( sequenceA ) . SelectMany( 
    a => ( sequenceB ) . Select( b => ... ) );
Run Code Online (Sandbox Code Playgroud)

也可能是一个逻辑上有效的翻译,虽然它不是我们实际执行的翻译.在LINQ实施的早期,这是我们选择的翻译.但是,当你在更多的from子句上堆积时,它会使lambdas嵌套越来越深,这会给编译器带来类型推断中的巨大问题.这种翻译选择破坏了编译器的性能,因此我们引入了透明的标识符机制,为我们提供了一种更便宜的方式来表示深度嵌套的范围的sentics.

如果这些科目对您感兴趣:

有关为什么深层嵌套的lambdas为编译器提出难题的更多想法,请参阅:

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/

  • 请注意,"C#语言规范"是可下载的Word文档,因此不会被大多数搜索引擎编入索引,也无法在线阅读.也许微软可能会在未来改变它! (7认同)

小智 9

var query = sequenceA.SelectMany(a => sequenceB.Select(b => ...));
Run Code Online (Sandbox Code Playgroud)

编辑:正如Eric Lippert在评论中所指出的,这给出了相同的结果,但故意不是如何在内部翻译.看到他的回答另一种方式来调用SelectMany,这与原始方式相对应.此外,b =>为清楚起见,添加了省略.