2013-03-20 25 views
4

據我瞭解,我可以用這個:C#表達式語法速記

Func<string> f1 =() => DateTime.Now.ToString(); 

爲速記:

Func<string> f2 =() => { return DateTime.Now.ToString(); }; 

我的問題是,爲什麼我不能做同樣的表情:

Expression<Func<string>> exp1 =() => DateTime.Now.ToString(); 
Expression<Func<string>> exp2 =() => { return DateTime.Now.ToString(); }; 

第二行不編譯。

+0

您不能將此特定類型的lambda(構成一個語句主體,即花括號)轉換爲表達式樹。您不能使用匿名方法 – Charleh 2013-03-20 14:27:36

+0

我認爲來自compilker的錯誤消息說明了這一切:「具有語句正文的lambda表達式不能轉換爲表達式樹」。至於爲什麼不這樣做:正如Eric Lipeprt經常發現的那樣,所有的表達原本都是沒有任何說明的,直到語言團隊決定實施它們的好處超過了這樣做的成本後才實施。 – 2013-03-20 14:28:46

+0

在第二種情況下,編譯器將生成代碼以構建表示lambda表達式的表達式樹。這與你的第一種情況不一樣 – NoviceProgrammer 2013-03-20 14:30:44

回答

3

編譯器以不同的方式處理這些對象。 第一個將編譯爲IL方法,該方法不會返回並返回DateTime.Now.ToString()。編譯器本身跳過的返回,並使其作爲

string myMethod() { return DateTime.Now.ToString(); } 

的第二個被genereted成LinqExpression對象,處理它以另一種方式,使得這樣的語法會導致錯誤。 雖然它們第一次看起來相同,但編譯器會爲它們生成不同的代碼。

您可以閱讀Why would you use Expression<Func<T>> rather than Func<T>?關於這兩個結構

1

Expressions<>小號不能用於報表,只表達而產生的差異。當你在表達式中加上大括號時,它變成了一個聲明/複合聲明。