2010-06-29 30 views
38

MSDN文檔狀態:LINQ的Expression.Quote方法的目的是什麼?

Expression.Quote

方法創建 UnaryExpression一個表示 表達具有式表達的一個恆定值 。

我已經能夠通過使用Expression類手動構建謂詞表達式來構建用於LINQ查詢的謂詞表達式,但從未遇到過需要Expression.Quote。

何時以及爲什麼要使用它?從我看到的LINQ表達式中,他們似乎只是在不添加任何值的情況下包裝現有的表達式。

Quote方法/節點類型的用途是什麼?

+0

「當您使用Expression.Call構造MethodCallExpression時,任何屬於lambda表達式(LambdaExpression/Expression )的參數必須在傳入之前使用Expression.Quote來包裝參數。」真的嗎?使用.Net 4.5,我能夠成功地通過裸表達式而不需要先用Expression.Quote()引用它們。 – 2013-09-11 00:09:21

+0

如果你的參數的類型是'Func <>',那麼確定你只需要這麼做,但是對於許多LINQ'IQueryable '擴展方法來說,參數類型實際上是'Expression >',在這種情況下你將需要'Expression.Quote'。我沒有試過用.NET 4.5來做這件事,但我認爲它是一樣的。在寫這篇文章的時候,我可能正在使用.NET 3.5。 – GiddyUpHorsey 2013-10-02 22:01:38

回答

23

Expression.Quote指定將lambda視爲表達式樹而不是函數。它引發操作數的閉包語義。

當您使用Expression.Call構建MethodCallExpression,是lambda表達式(LambdaExpression/Expression<TDelegate>)必須使用Expression.Quote傳遞之前包住參數。

所以對於Expression<Func<bool>>類型的參數,當您創建的任何參數實例如:() => true,表達的Type財產將Func<bool>而表達的類型(調用GetType)將Expression<Func<bool>>

因此,要獲得一個Expression,它具有Type屬性的正確值,您將lambda表達式傳遞到Expression.Quote並將其作爲參數傳遞給Expression.Call

我不得不通過反射器看看Expression.Quote並且當唯一的參數是Expression類型的,它必須從LambdaExpression派生並且這方法內檢查。出於興趣,任何人都知道MS爲什麼不只是使參數類型爲LambdaExpression

正如StevenH指出的,Expression.Quote用於實現LINQ查詢提供程序。 Queryable上採用lambda表達式(如Where,OrderBy,GroupBy等)的所有方法在內部構造MethodCallExpression,使用Expression.Call並將lambda表達式參數與Expression.Quote調用包裝在一起。

有關Expression.Quote的更多詳細說明,請閱讀answer

相關問題