Lambda Expression Tree Parsing

c# expression-trees lambda

Domanda

Sto cercando di utilizzare Lambda Expressions in un progetto per mappare a un'API di query di terze parti. Quindi, sto analizzando a mano l'albero delle espressioni.

Se passo in un'espressione lambda come:

p => p.Title == "title"

tutto funziona.

Tuttavia, se la mia espressione lambda è simile a:

p => p.Title == myaspdropdown.SelectedValue

Utilizzando il debugger .NET, non vedo il valore effettivo di tale funzione. Invece vedo qualcosa del tipo:

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

Cosa dà? E quando provo ad afferrare il lato destro dell'espressione come una stringa, ottengo (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue) invece del valore attuale. Come ottengo il valore reale?

Risposta accettata

Ricorda che quando hai a che fare con l'espressione lambda come un albero di espressioni, non hai codice eseguibile. Piuttosto hai un albero di elementi di espressione, che costituiscono l'espressione che hai scritto.

Charlie Calvert ha un buon post che ne parla in dettaglio. Incluso è un esempio di utilizzo di un visualizzatore di espressioni per il debug di espressioni.

Nel tuo caso, per ottenere il valore del lato destro dell'espressione di uguaglianza, dovrai creare una nuova espressione lambda, compilarla e quindi invocarla.

Ho violato un rapido esempio di questo - spero che fornisca ciò di cui hai bisogno.

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; }
}

Risposta popolare

Per ottenere il valore effettivo, è necessario applicare la logica dell'albero delle espressioni a qualsiasi contesto tu abbia.

L'intero punto di espressione alberi è che rappresentano la logica come dati piuttosto che valutare l'espressione. Avrai bisogno di capire cosa significa veramente l'espressione lambda. Ciò potrebbe significare valutare alcune parti di esso rispetto ai dati locali: dovrai decidere tu stesso. Gli alberi delle espressioni sono molto potenti, ma non è semplice analizzarli e usarli. (Chiedi a chiunque abbia scritto un provider LINQ ... Frans Bouma ha lamentato più volte le difficoltà).



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché