Lambda Expression Tree Parsing

c# expression-trees lambda

Frage

Ich versuche, Lambda Expressions in einem Projekt zu verwenden, um eine Abfrage-API einer dritten Partei zuzuordnen. Also analysiere ich den Ausdrucksbaum von Hand.

Wenn ich einen Lambda-Ausdruck übergebe wie:

p => p.Title == "title"

funktioniert alles.

Wenn mein Lambda-Ausdruck jedoch wie folgt aussieht:

p => p.Title == "title"

Mit dem .NET-Debugger sehe ich nicht den tatsächlichen Wert dieser Funktion. Stattdessen sehe ich etwas wie:

p => p.Title == "title"

Was gibt? Und wenn ich versuche, die rechte Seite des Ausdrucks als eine Zeichenfolge zu greifen, bekomme ich (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue) anstelle des tatsächlichen Werts. Wie bekomme ich den tatsächlichen Wert?

Akzeptierte Antwort

Denken Sie daran, dass Sie keinen ausführbaren Code haben, wenn Sie mit dem Lambda-Ausdruck als Ausdrucksbaum arbeiten. Eher haben Sie einen Baum von Ausdruckselementen, die den Ausdruck bilden, den Sie geschrieben haben.

Charlie Calvert hat einen guten Beitrag , der das ausführlich diskutiert. Enthalten ist ein Beispiel für die Verwendung eines Ausdrucks-Visualisierers zum Debuggen von Ausdrücken.

Um in Ihrem Fall den Wert der rechten Seite des Gleichheitsausdrucks zu erhalten, müssen Sie einen neuen Lambda-Ausdruck erstellen, ihn kompilieren und dann aufrufen.

Ich habe ein schnelles Beispiel dafür gehackt - hoffe, es liefert, was Sie brauchen.

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

Beliebte Antwort

Um den tatsächlichen Wert zu erhalten, müssen Sie die Logik des Ausdrucksbaums auf den Kontext anwenden, den Sie haben.

Der ganze Sinn von Ausdrucksbäumen besteht darin, dass sie die Logik als Daten darstellen, anstatt den Ausdruck zu bewerten. Sie müssen herausfinden, was der Lambda-Ausdruck wirklich bedeutet. Das kann bedeuten, dass Sie einige Teile davon mit lokalen Daten vergleichen - Sie müssen das selbst entscheiden. Ausdrucksbäume sind sehr mächtig, aber es ist nicht einfach, sie zu analysieren und zu verwenden. (Fragen Sie jemanden, der einen LINQ-Anbieter geschrieben hat ... Frans Bouma hat die Schwierigkeiten mehrmals beklagt.)




Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum