2012-02-02 72 views

回答

39

爲了您將來的參考,本表格的所有問題都由C#規範的第7.16節回答。

您的具體問題由本款回答:


與第二from子句後跟一個select條款

from x1 in e1 
from x2 in e2 
select v 

查詢表達式轉換成

(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實施的早期,這是我們選擇的翻譯。然而,當你在更多的子句上堆砌時,它會使得lambda嵌套越來越深,這就給編譯器帶來了巨大的類型推斷問題。這種翻譯的選擇破壞了編譯器的性能,所以我們引入了透明標識符機制,爲我們提供了一種更便宜的方法來表示深度嵌套作用域的seamntics。

如果這些科目的興趣你:

有關爲什麼深度嵌套lambda表達式存在一個難題編譯器來解決更多的想法,請參閱:

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文檔,因此不會被大多數搜索引擎索引,也不能在線閱讀。也許微軟未來可能會改變它! – 2015-09-11 18:55:08

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

編輯:在評論中指出的埃裏克利珀,這給了相同的結果,而是有意它不是如何在內部轉換。請參閱他的回答,以尋求另一種方式致電SelectMany,該方法確實與原件相符。另外,爲了清楚起見,添加了省略的b =>

+0

請問非嵌套的變種,比如'變種query = sequenceA.SelectMany(a => sequenceB).Select(...);'也可以工作嗎? – 2012-02-02 16:21:49

+0

@ OlivierJacot-Descombes這也是可能的,但這意味着您不能在第二個「Select」參數中引用'a'。 – hvd 2012-02-02 17:00:48

+0

@hdv:你們兩個都不對。你指出在奧利維爾的評論中,他已經失去了範圍變量'a'。但是在你的兩個翻譯中你都失去了範圍變量'b'。 'b'在你的翻譯中去了哪裏?如果'...'指的是'b'怎麼辦?你需要另一個lambda在那裏! – 2012-02-02 17:35:38

1

另一種方式來寫這將是:

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

''''語句和'SelectMany'的嵌套'使嵌套的枚舉扁平化。即他們將枚舉的枚舉轉換爲一個枚舉,其中包含源的嵌套枚舉的所有元素。他們不加入兩個無關的枚舉。 – 2014-09-30 16:12:55

+0

我所做的是交叉連接,與您列出的其他選項相同。結果枚舉也是平坦的。繼續嘗試 :) 。 – 2014-09-30 16:50:51

+0

示例:輸入'string [] [] nested = new string [] [] { \t new string [] {「a」,「b」,「c」}, \t new string [] {「AA」, 「BB」,「CC」,「DD」}, \t新字符串[] {「1」,「2」,「3」}, };'。預期輸出:a,b,c,AA,BB,CC,DD,1,2,3, – 2014-09-30 17:49:52