共用方式為


表達式樹

表示式樹狀結構 代表類似樹狀數據結構中的程式代碼,其中每個節點都是表達式,例如方法呼叫或二進位作業,例如 x < y

如果您使用 LINQ,您有豐富的連結庫體驗,其中 Func 類型是 API 集合的一部分。 (如果您不熟悉 LINQ,您可能想要在此教學課程之前閱讀 LINQ 教學課程和 Lambda 運算式 的相關文章。表達式樹狀架構提供與函式自變數更豐富的互動。

當您建立 LINQ 查詢時,通常會使用 Lambda 表達式撰寫函式自變數。 在典型的 LINQ 查詢中,這些函式自變數會轉換成編譯程式所建立的委派。

您已經撰寫使用表示式樹狀架構的程式代碼。 Entity Framework 的 LINQ API 接受 Expression 樹狀架構作為 LINQ 查詢運算式模式的自變數。 這可讓 Entity Framework 將您在 C# 中撰寫的查詢轉譯成在資料庫引擎中執行的 SQL。 另一個範例是 Moq,這是 .NET 的熱門模擬框架。

當您想要有更豐富的互動時,需要使用 運算式樹狀架構。 表達式樹將程式碼表示為可供您檢查、修改或執行的結構。 這些工具讓您能在運行時操控代碼。 您可以撰寫程式代碼來檢查執行中的演算法,或插入新功能。 在更進階的案例中,您可以修改執行中的演算法,甚至將 C# 運算式轉譯為另一種表單,以在另一個環境中執行。

您可以編譯並執行表示式樹狀架構所代表的程式代碼。 建置和執行表達式樹狀結構可讓您動態修改可執行的程式代碼、在各種資料庫中執行LINQ查詢,以及建立動態查詢。 如需 LINQ 中表示式樹狀架構的詳細資訊,請參閱 如何使用表示式樹狀架構來建置動態查詢

表達式樹狀架構也用於動態語言執行平臺 (DLR),以提供動態語言與 .NET 之間的互作性,並讓編譯程式寫入器發出表達式樹狀架構,而不是Microsoft中繼語言 (CIL)。 如需 DLR 的詳細資訊,請參閱 動態語言執行平臺概觀

您可以讓 C# 或 Visual Basic 編譯程式根據匿名 Lambda 運算式為您建立表示式樹狀結構,也可以使用 命名空間手動 System.Linq.Expressions 建立表達式樹狀結構。

將 Lambda 運算式指派給 類型的 Expression<TDelegate>變數時,編譯程式會發出程式代碼來建置代表 Lambda 表達式的運算式樹狀結構。

下列程式代碼範例示範如何讓 C# 編譯程式建立代表 Lambda 運算式 num => num < 5的表達式樹狀結構。

Expression<Func<int, bool>> lambda = num => num < 5;

您可以在程式代碼中建立表示式樹狀架構。 您可以通過建立每個節點,然後將它們連結成樹狀結構來建構樹。 您將瞭解如何在建置運算式樹一文中建立運算式。

表達式樹狀結構是不可變的。 如果您想要修改表達式樹狀結構,您必須複製現有的表達式樹狀結構並取代其中節點,以建構新的表達式樹狀結構。 您使用表達式樹遍歷器來遍歷現有的表達式樹。 如需詳細資訊,請參閱有關翻譯表達式樹的文章。

建置表達式樹狀結構之後,您會 執行表達式樹狀結構所代表的程序代碼

局限性

C# 編譯程式只會從表達式 Lambda (或單行 Lambda) 產生表達式樹狀架構。 它無法剖析語句 Lambda(或多行 Lambda)。 如需 C# 中 Lambda 表達式的詳細資訊,請參閱 Lambda 運算式

有一些較新的 C# 語言元素無法很好地轉譯成表達式樹狀結構。 表達式樹狀架構不能包含 await 表達式或 async lambda 表達式。 C# 6 和其後版本新增的許多功能,在表達式樹中並未以完全相同的方式出現。 較新的功能反而會在表達式樹中儘可能使用同等的早期語法來呈現。 其他建構無法使用。 這表示當引進新的語言功能時,解譯表達式樹狀架構的程式代碼的運作方式相同。 不過,即使有這些限制,表達式樹狀架構也可讓您建立動態演算法,依賴解譯和修改以數據結構表示的程序代碼。 它可讓 Entity Framework 等豐富連結庫完成其作業。

表達式樹狀結構不支援新的表達式節點類型。 對於解譯表達式樹狀架構的所有連結庫來說,這將是一項重大變更,以引進新的節點類型。 下列清單包含無法使用的大部分 C# 語言元素: