2012-03-18 33 views
4

我總是對這個東西感到困惑。C#編譯器看到Fluent語法或查詢表達式?

我有這個疑問:

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; 

IEnumerable<string> query = names.Where(n => n.Contains("a")) 
.OrderBy(n => n.Length) 
.Select(n => n.ToUpper()); 

我在一個book,上面寫着:

編譯器通過翻譯它處理查詢表達式爲 流利的語法

但是在Reflector中我看到了相反的結果: Reflector Code

這不是流利的語法。

那麼編譯器看到了什麼?

+14

反射器顯示你希望你看到什麼。 – user7116 2012-03-18 21:18:02

+2

你應該用反彙編看了;) – 2012-03-18 21:19:29

+0

@sixlettervariables所以'編譯器通過翻譯成通順syntax.'它意味着IL是建基於良好的語法處理查詢表達式? – 2012-03-18 21:22:36

回答

18

A「編譯」是由定義其轉換一種語言編寫成另一種語言的文本的裝置。

C#編譯器將包含查詢表達式的C#程序邏輯轉換爲C#-without-query-expressions,然後將程序轉換爲IL。(請注意,它不需要實際上做翻譯的是中期的,它必須表現好像它這樣做,但如果編譯器作者是足夠聰明的可以跳過中間步驟,仍然可以得到正確的輸出,那麼我們肯定能這樣做的。)

反光也是一個編譯器。它將IL轉換爲C#。它是如何做的是它的業務。

你不能讓什麼的C#編譯器基於反射輸出的任何結論;他們是由不同的人寫的完全不同的程序來解決不同的問題。

+0

是跳過中間步驟,以避免維護兩個代碼庫的原因的一部分?或者這是從支持L2S/L2EF出生的嗎? – user7116 2012-03-18 22:23:37

+0

嗨,Eric,所以 - (根據附加鏈接)'編譯器將aquery表達式翻譯成流利的語法'然後寫入'IL'?這是對的嗎 ? – 2012-03-19 07:37:55

+1

@RoyiNamir:是的,這是正確的。查詢表達式只是流利形式的「語法糖」。如果你感興趣的話,C#規範有一個部分可以準確描述轉換的內容。 – 2012-03-19 14:36:04

6

查詢理解語法直接編譯到方法調用中;他們產生難以區分的IL。

但是,許多反編譯器總是會將LINQ調用轉換爲查詢理解語法。
YOu可能可以在選項中更改該行爲。

+0

我在哪裏可以看到它實際上轉換爲流暢的語法? – 2012-03-18 21:26:59

+2

@RoyiNamir:在ildasm中,或通過在反射器中禁用該選項。 – SLaks 2012-03-18 21:27:53

+1

@RoyiNamir:沒有「流利的語法」的概念。我想這只是書的作者的表達。 – Tigran 2012-03-18 21:28:31

3

股票csc編譯器將任何和所有的語法爲IL,流利或以其他方式。你正在看的是由Reflector選擇的重建。

某些語法是簡單的糖更復雜的構造在引擎蓋下,和query expressions are one of these examples。其他例子包括foreach loopslambda expressions

現在,如果這是的LINQ to SQL或實體,查詢語法,流利的語法是這樣實現的表情和靠引擎蓋下的供應商翻譯。這與L2O不一樣。

+0

我在哪裏可以看到它實際上翻譯成流利的語法? – 2012-03-18 21:26:44

+0

@RoyiNamir:你是什麼意思?無論Linq to Objects場景如何,編譯器都會輸出IL。 – user7116 2012-03-18 21:27:41

1

我相信你向後讀這(但我可能是錯誤的)

它是什麼想說的是,

from n in names 
where n.Contains("a") 
orderby n.Length 
select n.ToUpper() 

轉化爲

names 
.Where(n => n.Contains("a")) 
.OrderBy(n => n.Length) 
.Select(n => n.ToUpper()); 
+0

是的多數民衆贊成我的意思是 – 2012-03-18 21:23:14

0

我覺得說「流利語法「的書意味着LINQ隊列的Deferred Execution。 僅當根據數據的實際請求時,基於之前完成的所有查詢(如果有的話)生成查詢。分析之前完成的所有查詢,並且單個(如果可能的話)優化生成的LINQ查詢以獲取數據。

但從最終結果來看,像其他人一樣mantioned,它總是最終成爲集IL指令。