C # 4.0: Árboles de expresión vs. CodeDom

c# codedom expression-trees

Pregunta

¿Cuáles son las diferencias entre los árboles de expresiones y CodeDom? ¿Qué debo usar para qué escenario?

Respuesta aceptada

Los árboles de expresiones tienen mucho en común con (por ejemplo) un AST . No se asigna directamente al código, pero es muy susceptible a la construcción a partir de algoritmos. Por ejemplo, si está analizando una fórmula:

((a + 2) / b)

es decir:

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

De hecho, he hecho exactamente esto, utilizando un analizador que construye un árbol de objetos, con objetos que generan la expresión completa a través de una implementación "visitante". En .NET 4.0, el soporte de árbol de expresiones más rico hace posible admitir la mayoría de los escenarios y compilarlo a pedido.

Otro uso clave de las expresiones es que puede deconstruirlas en tiempo de ejecución, por lo que en su código podría tener:

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

y extraiga la SomeMethod método SomeMethod , 1 y "abc" etc.


Codedom se asigna al código . Se trata de declaraciones, etc., muy similares a cómo escribiría un código regular. El uso más común de código es para la generación de código, como parte de herramientas. Se puede utilizar para la compilación dinámica, pero para ser honesto es más difícil. No soy un fan. La buena característica es que un árbol de código podría funcionar para múltiples idiomas.


Otro contendiente aquí debería ser DynamicMethod y / o ILGenerator . Esto no se asigna a un AST (expresión) y no se puede utilizar para generar código fuente (código), pero permite un acceso completo a las herramientas de MSIL. Por supuesto, también requiere que pienses en términos de pilas, etc., pero es muy eficiente y efectivo para la meta-programación.


Si ILGenerator es un núcleo demasiado duro y el código es un PITA, entonces otra opción es la generación de código en tiempo de ejecución como una cadena . Luego pase eso a través de CSharpCodeProvider para compilarlo. Hay partes del tiempo de ejecución del núcleo que hacen esto ( XmlSerializer IIRC).


Para resumir:

  • meta-programación: ILGenerator o CSharpCodeProvider ; también Expression en 4.0 (pero esto es bastante limitado en 3.5)
  • manejo de AST: Expression
  • Análisis en tiempo de ejecución: Expression
  • Generación de código en múltiples idiomas: Code-dom

Respuesta popular

Los árboles de expresión se utilizan para construir expresiones. Creación de código fuente en tiempo de ejecución. CodeDom se utiliza para compilar el código fuente. Tiene que existir antes de que puedas construirlo. Los árboles de expresión son más flexibles, pero mucho más difíciles de usar.

Si desea agregar secuencias de comandos a su aplicación, use CodeDom. Si quieres hacer una reflexión muy avanzada y los Me gusta, usa árboles de expresiones, pero no lo recomiendo.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué