C#4.0:表達式樹與CodeDom

c# codedom expression-trees

Expression樹和CodeDom有什麼區別?我應該在哪種情況下使用哪個?

一般承認的答案

表達式樹與(例如) AST有許多共同之處。它不直接映射到代碼,但非常適合從算法構造。例如,如果要解析公式:

((a + 2) / b)

那是:

ParameterExpression a = ..., b = ...
var body = Expression.Divide(
    Expression.Add(a, Expression.Constant(2)),
    b);
var lambda = Expression.Lambda(body,a,b); // optionally with generics

實際上,我已經完成這個,使用構建對象樹的解析器,通過“訪問者”實現生成完整表達的對象。在.NET 4.0中,更豐富的表達式樹支持使得支持大多數場景成為可能,並根據需要進行編譯。

表達式的另一個關鍵用途是您可以在運行時解構它們,因此在您的代碼中您可能具有:

Foo(x => x.SomeMethod(1, "abc"));

並提取SomeMethod方法SomeMethod1"abc"等。


codedom映射到代碼 。它完全與語句等有關,與編寫常規代碼的方式非常相似。編碼器的最常見用途是用於代碼生成,作為工具的一部分。您可以將它用於動態編譯,但說實話它更難。我不是粉絲。好的功能是編碼樹可能適用於多種語言。


這裡的另一個競爭者應該是DynamicMethod和/或ILGenerator 。這不會映射到AST(表達式),也不能用於生成源代碼(codedom),但允許完全訪問MSIL工具。當然,它還需要您考慮堆棧等,但它對元編程非常有效和高效。


如果ILGenerator太硬核,而且encodeom是PITA,那麼另一種選擇是將代碼運行時生成為字符串 。然後通過CSharpCodeProvider傳遞它來編譯它。核心運行時的某些部分可以執行此操作( XmlSerializer IIRC)。


總結一下:

  • 元編程: ILGeneratorCSharpCodeProvider ; 4.0中的Expression (但這在3.5中非常有限)
  • 處理AST: Expression
  • 在運行時解析: Expression
  • 多種語言的代碼生成:代碼

熱門答案

表達式樹用於構建表達式。在運行時創建源代碼。 CodeDom用於編譯源代碼。它必須存在才能構建它。表達式樹更靈活,但使用起來更難。

如果要向應用程序添加腳本,請使用CodeDom。如果你想做非常高級的反射和喜歡,使用表達式樹,但我不推薦它。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow