2009-10-07 16 views
16

Este fue inspirado por mi compañero de trabajo de gurú del lenguaje que no parece encontrar un buen uso para ellos, y después de algunos intentos cojos propios, tendría que estar de acuerdo.¿Cuál es un buen caso de uso para .net 4.0 Expression Trees?

Ahora sé que estos conceptos tienden a fluir mucho más fácilmente una vez que se obtienen algunas buenas razones prácticas.

Por el momento parece que su único propósito es permitirle escribir a un proveedor de Linq?

es que ?? ¿Hay algún otro beneficio para esto?

+3

http://stackoverflow.com/questions/403088/practical-use-of-expression-trees –

Respuesta

15

árbol de expresión son tan poderosos porque permiten tratar código como datos. Los usuarios están acostumbrados a acumular datos, guardarlos y volver más tarde.

Los árboles de expresiones le permiten hacer lo mismo con el código. Por ejemplo, puede tomar la entrada de su usuario (casillas de verificación, rangos de números, etc.) y traducirla a un árbol de Expresión. Ese árbol de expresiones se puede ejecutar o almacenar para su uso posterior. Muy genial.

Piense en los usos prácticos relacionados con la creación de informes y el almacenamiento de filtros de datos y asignaciones de datos. Otro uso práctico sería apoyar flujos de trabajo personalizados en su aplicación en función de las reglas definidas por el usuario.

Aquí hay un poco de código de MSDN en la serialización de árboles de expresiones (http://code.msdn.microsoft.com/exprserialization) que debería hacer fluir las ideas.

+0

¡Genial! Esta es una respuesta que se ajusta a mi mentalidad particular. Buenos ejemplos! Veo ahora cómo esto se usa en otras partes del marco. Entonces, ¿esto se usa mucho en WPF? – KevinDeus

+0

Gracias. Me alegro de que ayudó. He pensado (probablemente demasiado) sobre WPF y sobre cómo los conceptos útiles de programación funcional como lambdas y los árboles de expresión habrían estado en el núcleo. El problema es que WPF fue lanzado con .NET 3.0 y LINQ fue lanzado en .NET 3.5. De ahora en adelante, espero que los equipos de WPF/Silverlight se reorganizarán. XAML estaría bien, excepto por todas las malditas cadenas :). Encienda Relector y vea lo que tenían que hacer para cosas como System.Windows.DataTrigger. Su lamentación puede haber sido un catalizador para LINQ. –

3

.NET 4.0 Los árboles de expresiones son también la base para DLR AST de

8

Puede utilizar los árboles de expresión para transformar un lenguaje de dominio en código ejecutable.

1

He tenido una buena experiencia con ellos transformando mi lenguaje específico de dominio AST en árboles de expresión. También es bastante fácil con un adaptador de árbol ANTLR crear un árbol de expresiones directamente desde la gramática.

4

Una solución que busca un problema ¿eh?

Los árboles de expresiones le permiten presentar el código como una estructura de datos transformable, por lo tanto, son perfectos para transformar idiomas Linq To SQL es el más poderoso actualmente.

Otro uso aparte de las DSL (que es la transformación) es la paralelización (que es spliting) y el ejemplo en ese espacio es PLINQ.

+0

sí una solución que buscan para un problema como Twitter :) – Surya

1

Puede usar el árbol de expresiones como un generador de código con un nivel de abstracción más alto que el ensamblado emitido y más rápido que CodeCompiler. Aquí hay algunas pruebas del concepto que utilicé para convencer a nuestro equipo de que las usara como reemplazo de CodeCompiler.

[TestClass] 
public class WhenINeedToAccessPropertiesByNameHavingATypeReference 
{ 
    public class SomeCategoryData 
    { 
     public DateTime CreatedDate { get; set; } 
    } 

    [TestMethod] 
    public void ICanDoThatWithAnExpressionAndItPerformsWell() 
    { 
     // INIT 

     var someCategoryData = 
      Enumerable.Range(1970, 100).Select(year => 
       new SomeCategoryData { CreatedDate = new DateTime(year, 1, 1) }).Cast<object>(); 
     var t = typeof(SomeCategoryData); // or it can be: t = someCategoryData.First().GetType(); 
     var compiled = Stopwatch.StartNew(); 

     // ACT 

     var filter = AccessPropertyByNameInCompiledMannerSomehow(t, "CreatedDate"); 

     // ASSERT 

     Trace.WriteLine(string.Format("compiled in: {0}", compiled.Elapsed)); 
     Assert.IsTrue(compiled.ElapsedMilliseconds < 3, "compiles fast enough"); 

     var executed = Stopwatch.StartNew(); 

     // ACT 
     List<object> result = null; 
     for (var i = 0; i < 10000; i++) 
     { 
      result = someCategoryData.Where(d => filter(d, new DateTime(2000, 1, 1), new DateTime(2009, 1, 1))) 
       .ToList(); 
     } 
     executed.Stop(); 
     Trace.WriteLine(string.Format("executed in: {0}", executed.Elapsed)); 

     // ASSERT 
     Assert.AreEqual(10, result.Count, "insure compiled code actually works"); 
     Assert.IsTrue(executed.ElapsedMilliseconds < 300, "runs fast enough"); 
    } 

    private static Func<object, DateTime, DateTime, bool> 
     AccessPropertyByNameInCompiledMannerSomehow(Type t, string fieldToFilterBy) 
    { 
     var objectParameter = Expression.Parameter(typeof(object), "p"); 
     var instance = Expression.Convert(objectParameter, t); 
     var lower = Expression.Parameter(typeof(DateTime), "l"); 
     var upper = Expression.Parameter(typeof(DateTime), "u"); 

     var composite = Expression.Lambda<Func<object, DateTime, DateTime, bool>>(
      Expression.And(
       Expression.LessThanOrEqual(
        lower, 
        Expression.PropertyOrField(instance, fieldToFilterBy) 
        ), 
       Expression.GreaterThanOrEqual(
        upper, 
        Expression.PropertyOrField(instance, fieldToFilterBy) 
        ) 
       ), objectParameter, lower, upper 
      ); 

     return composite.Compile(); 
    } 
} 
2

La respuesta rápida es "no, no es solo para los proveedores de LINQ ahora". Primero, los árboles de expresión fueron extendidos por el tiempo de ejecución dinámico del lenguaje para soportar lenguajes dinámicos. Básicamente, si quieres portar tu propio lenguaje dinámico a .NET (como IronPython e IronRuby), tendrás que usar árboles de expresiones. OK, no muchas personas tienen sus propios idiomas. ¿Cuáles son otros casos de uso? Uno de ellos es generar código dinámico en tiempo de ejecución.Tengo un ejemplo aquí: Generating Dynamic Methods with Expression Trees in Visual Studio 2010. Explica cómo puede usar los ET en lugar de generar MSIL para crear métodos dinámicos. De hecho, hay algunos casos de uso para Expression Trees fuera de LINQ incluso en .NET 3.5, pero esas publicaciones aún no se han escrito.

1

Tengo algunos ejemplos here

(lo del formato de código roto)

Cuestiones relacionadas