運算式樹讓 Lambda 運算式以記憶體中樹狀資料結構呈現,而非編譯為可執行 IL。這是 LINQ to SQL、Entity Framework、動態查詢建構、規則引擎的基石。
Func<int, int> f = x => x + 1; // 委派:可執行程式碼
Expression<Func<int, int>> e = x => x + 1; // 運算式樹:資料結構
f(5) → 回傳 6e.Compile()(5) 先編譯再執行,或遍歷 e.Body、e.Parameters 分析結構D → 亦可轉換為 Expression<D>{ return ...; })System.Linq.Expressions.Expression 及其衍生類別:
ParameterExpression:參數節點ConstantExpression:常數值BinaryExpression:二元運算(+、-、==、&& 等)MethodCallExpression:方法呼叫MemberExpression:屬性/欄位存取LambdaExpression:根節點,含 Parameters、BodyExpression<Func predicate = p => p.Price > 100;
if (includeDiscontinued)
predicate = predicate.And(p => !p.Discontinued);
var results = db.Products.Where(predicate).ToList();
Entity Framework 遍歷運算式樹,轉譯為 SQL:
var query = db.Users.Where(u => u.Name.StartsWith("A"));
// EF 分析運算式樹 → 生成:SELECT * FROM Users WHERE Name LIKE 'A%'
var rules = new List<Expression<Func<Order, bool>>> {
o => o.Total > 0,
o => o.Items.Any(),
o => o.Customer.IsActive
};
// 執行時編譯或解譯執行
public class ExpressionPrinter : ExpressionVisitor {
protected override Expression VisitBinary(BinaryExpression node) {
Console.Write("(");
Visit(node.Left);
Console.Write($" {node.NodeType} ");
Visit(node.Right);
Console.Write(")");
return node;
}
}
// 遍歷並列印結構
除 Lambda 隱含轉換外,可用 Expression 靜態工廠方法手動建構:
var x = Expression.Parameter(typeof(int), "x");
var body = Expression.Add(x, Expression.Constant(1));
var lambda = Expression.Lambda<Func<int, int>>(body, x);
var compiled = lambda.Compile(); // 動態生成 IL,效能接近靜態程式碼
Compile() 有額外成本,適用於重複使用的動態邏輯運算式樹將 C# 從「靜態編譯語言」推向「具備執行期程式碼分析與轉譯能力的語言」,是現代資料存取層、動態邏輯框架不可或缺的基礎設施。