玩轉C#之【表達式目錄樹】

2022/09/15閱讀時間約 3 分鐘

環境安裝

這邊可以先安裝Expression Tree Visualizer工具
Viusla studio 2019 安裝方式:
檔案(ExpressionTreeVisualizer.2019)下載完之後,將檔案複製到此目錄:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Packages\Debugger
📷

介紹

首先它來自Sysyem.Linq.Expressions命名空間,用以下的範例做個解說
static void Main(string[] args)
{
Func<int, int, int> func1 = (m, n) => m * n + 2;
Expression<Func<int, int, int>> exp = (m , n) => m * n + 2;

}
我們先觀察如果是一個委派VisualStudio會怎麼做解析,它會有一個Method跟Target
📷
在觀察如果是Expressions,其實就只是把代碼列出來的感覺一樣
📷
我們再透過上述提到的工具ExpressionTreeVisualizer觀察看看,它告訴了我們這個表達式樹是一個Func<int,int,int>類型的表達式樹,表達式目錄樹本質上是一個資料結構,資料結構中有幾個重要元素,其中包含這是屬於什麼類型的資料Lambda,並且body是它的核心,我們可以看出它也是一個表達式
📷
可以從中看出它是一個簡單的二元表達式,從這個表達式中可以看出它的資料類型是Add,並且會有右邊和左邊的概念,右邊是一個常數,左邊是一個相乘的表達式
📷
從圖中可以看出,左邊跟右邊的類型都是屬於參數表達式
📷
從上述的解析過程我們可以發現,其實就是一個二元樹的資料結構
📷
表達式目錄樹=>是一種資料結構,可以被二元樹解析
:notes: 表達式目錄樹只能一行,無法帶入{ }
錯誤範例:
Expression<Func<int,int,int>> exp1 = (m,n) =>
{
return m*n+2
};
:notes:表達式目錄樹可以透過Compile方法,得到一個委派
int iResult1 = func.Invoke(12,23);
int iResult2 = exp.Compile().Invoke(12,23);
我們可以看一下,其實LINQ語法裡面傳遞的其實是表達式目錄樹,為什麼不能傳遞委派,因為委派的方法我們只能直接執行,沒辦法把它轉換成SQL語法的,我們在這裡傳遞得表達式目錄樹最終是要拆解成SQL語法。
📷

動態拼裝表達式目錄樹和擴展應用

我們來反編譯一下,此程式
Expression<Func<int, int, int>> exp = (m , n) => m * n + 2;
反編譯後會產生以下的程式
📷
並且我們在做下整理與比較
📷
從上述的比較可以看出 表達式目錄樹 有兩種宣告方式
範例解析:
📷
總結:
  • 可以用來替代反射,因為反射可以通用,但是性能不夠
  • 產生硬程式碼,可以提升性能
關於解析表達式目錄樹,生成SQL、表達式目錄樹拼裝連接之後會專門寫一篇文章跟大家講解

參考資料

本篇已同步發表至個人部落格
https://moushih.com/2022ithome15/
鐵人賽文章
為什麼會看到廣告
8會員
39內容數
我是這個部落格的作者,喜歡分享有關投資 💰、軟體開發 💻、占卜 🔮 和虛擬貨幣 🚀 的知識和經驗。
留言0
查看全部
發表第一個留言支持創作者!