Análisis de Lambda Expression Tree

c# expression-trees lambda

Pregunta

Estoy tratando de usar Lambda Expressions en un proyecto para asignarlo a una API de consulta de terceros. Entonces, estoy analizando el árbol de Expresión a mano.

Si paso en una expresión lambda como:

p => p.Title == "title"

Todo funciona.

Sin embargo, si mi expresión lambda se ve como:

p => p.Title == myaspdropdown.SelectedValue

Al usar el depurador .NET, no veo el valor real de esa función. En cambio veo algo como:

p => p.Title = (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue)

¿Lo que da? Y cuando intento capturar el lado derecho de la expresión como una cadena, obtengo (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue) lugar del valor real. ¿Cómo obtengo el valor real?

Respuesta aceptada

Recuerda que cuando tratas con la expresión lambda como un árbol de expresiones, no tienes código ejecutable. Más bien, tiene un árbol de elementos de expresión, que conforman la expresión que escribió.

Charlie Calvert tiene una buena publicación que discute esto en detalle. Se incluye un ejemplo del uso de un visualizador de expresiones para la depuración de expresiones.

En su caso, para obtener el valor del lado derecho de la expresión de igualdad, deberá crear una nueva expresión lambda, compilarla y luego invocarla.

He pirateado juntos un ejemplo rápido de esto: espero que ofrezca lo que necesita.

public class Class1
{
    public string Selection { get; set; }

    public void Sample()
    {
        Selection = "Example";
        Example<Book, bool>(p => p.Title == Selection);
    }

    public void Example<T,TResult>(Expression<Func<T,TResult>> exp)
    {
        BinaryExpression equality = (BinaryExpression)exp.Body;
        Debug.Assert(equality.NodeType == ExpressionType.Equal);

        // Note that you need to know the type of the rhs of the equality
        var accessorExpression = Expression.Lambda<Func<string>>(equality.Right);
        Func<string> accessor = accessorExpression.Compile();
        var value = accessor();
        Debug.Assert(value == Selection);
    }
}

public class Book
{
    public string Title { get; set; }
}

Respuesta popular

Para obtener el valor real, debe aplicar la lógica del árbol de expresiones al contexto que tenga.

Todo el punto de los árboles de expresión es que representan la lógica como datos en lugar de evaluar la expresión. Tendrá que averiguar qué significa realmente la expresión lambda. Eso puede significar evaluar algunas partes de la misma en función de los datos locales. Deberá decidirlo usted mismo. Los árboles de expresión son muy poderosos, pero no es una cuestión simple analizarlos y usarlos. (Pregúntele a cualquiera que haya escrito un proveedor de LINQ ... Frans Bouma ha lamentado las dificultades varias veces).



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