C#3.0新增功能10 表達式樹 03 支持表達式樹的框架類型

  • 2019 年 10 月 4 日
  • 筆記

存在可與表達式樹配合使用的 .NET Core framework 中的類的大型列表。 可以在 System.Linq.Expressions 查看完整列表。 讓我們來了解一下 framework 類的設計方式,而不是逐一查看完整列表。

在語言設計中,表達式是可計算並返回值的代碼主體。 表達式可能非常簡單:常數表達式 1 返回常數值 1。 它們可能更複雜:表達式 (-B + Math.Sqrt(B*B - 4 * A * C)) / (2 * A) 返回二次方程的一個根(若方程有解)。

System.Linq.Expression

使用表達式樹的其中一個難點在於許多不同類型的表達式在程序中的許多位置均有效。 請思考一個賦值表達式。 賦值的右側可以是常數值、變量、方法調用表達式或其他內容。 語言靈活性意味着,遍歷表達式樹時,可能會在樹的節點中的任意位置遇到許多不同的表達式類型。 因此,使用基表達式類型時,理解起來最簡單。 但是,有時你需要了解更多內容。 為此,基表達式類包含 NodeType 屬性。 它將返回 ExpressionType,這是可能的表達式類型的枚舉。 知道節點的類型後,可以將其轉換為該類型,並執行特定操作(如果知道表達式節點的類型)。 可以搜索特定的節點類型,然後使用這種表達式的特定屬性。

例如,此代碼將打印變量訪問表達式的變量的名稱。 我的做法是,先查看節點類型,再轉換為變量訪問表達式,然後查看特定表達式類型的屬性:

Expression<Func<int, int>> addFive = (num) => num + 5;                if (addFive.NodeType == ExpressionType.Lambda)              {                  var lambdaExp = (LambdaExpression)addFive;                    var parameter = lambdaExp.Parameters.First();                    Console.WriteLine("參數名稱:" + parameter.Name);                  Console.WriteLine("參數類型:" + parameter.Type);              }                Console.ReadKey();          }

輸出結果:

創建表達式樹

System.Linq.Expression 類還包含許多創建表達式的靜態方法。 這些方法使用為子節點提供的參數創建表達式節點。 通過這種方式,可以從其葉節點構建一個表達式。 例如,此代碼將生成一個 Add 表達式:

// 加法是「1+2」的加法表達式  var one = Expression.Constant(1, typeof(int));  var two = Expression.Constant(2, typeof(int));  var addition = Expression.Add(one, two);

從這個簡單的示例中,你會發現創建和使用表達式樹涉及了許多類型。 該複雜性是提供由 C# 語言提供的豐富詞彙的功能所必需的。

導航 API

存在映射到 C# 語言的幾乎所有語法元素的表達式節點類型。 每種類型都有針對該種語言元素的特定方法。 需要一次性記住的內容很多。 我不會記住所有內容,而是會採用有關使用表達式樹的技巧,如下所示:

  1. 查看 ExpressionType 枚舉的成員以確定應檢查的可能節點。 如果想要遍歷和理解表達式樹,這將非常有用。
  2. 查看 Expression 類的靜態成員以生成表達式。 這些方法可以從其子節點集生成任何表達式類型。
  3. 查看 ExpressionVisitor 類,以生成一個經過修改的表達式樹。