¿Cuál es el propósito de la clase de expresión?

c# expression-trees lambda

Pregunta

Me pregunto cuál es exactamente la diferencia entre envolver un delegado dentro de Expression<> y no.

Estoy viendo que Expression<Foo> se usa mucho con LinQ, pero hasta ahora no he encontrado ningún artículo que explique la diferencia entre esto, y solo use un delegado.

P.ej

Func<int, bool> Is42 = (value) => value == 42;

contra

Expression<Func<int, bool>> Is42 = (value) => value == 42;

Respuesta aceptada

Al almacenar un lambda como delegado, está almacenando una instancia específica de un delegado que realiza alguna acción. No se puede modificar, solo llámalo. Una vez que tenga su delegado, tiene opciones limitadas para inspeccionar lo que hace y otras cosas.

Al almacenar un lambda como una expresión, está almacenando un árbol de expresiones que representa al delegado. Puede ser manipulado para hacer otras cosas como cambiar sus parámetros, cambiar el cuerpo y hacer que haga algo radicalmente diferente. Incluso se podría compilar de nuevo a un delegado, así que puede llamarlo si lo desea. Puede inspeccionar fácilmente la expresión para ver cuáles son sus parámetros, qué hace y cómo lo hace. Esto es algo que un proveedor de consultas puede usar para entender y traducir una expresión a otro idioma (como escribir una consulta SQL para un árbol de expresión correspondiente).

También es mucho más fácil crear un delegado dinámicamente utilizando expresiones que emitiendo el código. Puede pensar en su código en un nivel superior como expresiones que son muy similares a cómo un compilador ve el código en lugar de ir a un nivel bajo y ver su código como instrucciones de IL.

Así que con una expresión, eres capaz de hacer mucho más que un simple delegado anónimo. Aunque no es realmente gratuito, el rendimiento se verá afectado si ejecuta expresiones compiladas en comparación con un método normal o un delegado anónimo. Pero eso podría no ser un problema, ya que los otros beneficios de usar expresiones pueden ser importantes para usted.


Respuesta popular

Func<> es solo un tipo de delegado. Una expresión es una representación en tiempo de ejecución del árbol completo de operaciones que, opcionalmente, puede compilarse en tiempo de ejecución en un delegado. Es este árbol el que analizan los analizadores de expresiones como Linq-to-SQL para generar sentencias SQL o hacer otras cosas inteligentes. Cuando asigna un lambda a un tipo de expresión, el compilador genera este árbol de expresión, así como el código IL habitual. Más sobre árboles de expresión .



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow