2011-12-07 62 views
8

從C#:在深度轉換lambda表達式到表達樹

並非所有lambda表達式可被轉換爲表達式樹。你 不能用一個語句塊(甚至只是一個 返回語句)將lambda轉換爲表達式樹 - >它必須是 的形式,它只計算一個表達式。

由於LINQ到對象語句不被轉換成表達式樹的對象,與LINQ到對象操作者使用拉姆達表達式可以包含語句塊

 string[] count = { "one ", "two ", "three ", "four ", "five ", "six " }; 
     IEnumerable<int> result = count.Select(item => 
           { 
            Console.WriteLine(item); 
            return item.Length; 
           }); 
     foreach (int i in result); 

OUTPUT:

one two three four five six 

我還沒有開始學習LINQ到SQL或LINQ到實體,但我認爲與上IQueryable<T>操作LINQ語句中永遠只能包含一個表達式lambda表達式,由於restristion只有一個表達式可以轉換爲表達式樹?

謝謝

回答

14

這不只是他們只能包含一個表達式 - 這不能成爲聲明拉姆達可言。即使是這樣的塊:

var result = query.Select(item => { return item.Length; }); 

對於LINQ to SQL將無效。它必須被表示爲:

var result = query.Select(item => item.Length); 

(我剛剛注意到,那就是你引用了該書的位哦 - 它顯示我是一致的:)

注意,作爲.NET 4,表達式樹自身有能力包含塊,但C#編譯器不能將語句lambdas翻譯成那種表達式樹。還有其他限制,但它們很少引起問題。

並非所有的匿名函數可以被表示爲表達式樹:

這部分中的C#4規範的4.6中指定。例如,包含賦值表達式的聲明體和匿名函數的匿名函數無法表示。在這些情況下,轉換依然存在,但在編譯時會失敗。

+5

現在,你究竟會知道** C#深度中提到的東西**?哦,沒關係。 –

+0

非常感謝你兩位 – AspOnMyNet

+0

@Jon:我突然想到這個問題與這個問題有多相關,在http://stackoverflow.com/questions/8405423/do-at-compile-time-linq-to-objects-陳述也得到翻譯成表達* wink wink * – AspOnMyNet

1

你是對的,他們只能包含一個表達式。