Ausdruck Bäume für dummies?
Ich bin der dummy in diesem Szenario.
Ich habe versucht, auf Google Lesen, was diese sind, aber ich verstehe es einfach nicht. Kann mir jemand eine einfache Erklärung dafür, was Sie sind und warum Sie nützlich?
edit: ich Rede von der LINQ-Funktion in .Net.
- Ich weiß, dieser post ist ziemlich alt, aber ich habe auf der Suche in Expression Trees in letzter Zeit. Ich Interessierte mich, nachdem ich begann mit Fluent NHibernate. James Gregory ausgiebig verwendet, was ist bekannt als statische Reflexion und er hat ein intro: jagregory.com/writings/introduction-to-static-reflection, um Zu sehen, statischen Reflexion und expression trees in Aktion, überprüfen Sie heraus die Fluent-NHibernate-source-code (fluentnhibernate.org). Es ist sehr sauber und ein sehr cooles Konzept.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die beste Erklärung, die über das expression-Bäume, die ich je gelesen ist dieser Artikel von Charlie Calvert.
Um es zusammenzufassen;
Einen Ausdruck-Baum repräsentiert was Sie tun wollen, nicht wie Sie wollen, es zu tun.
Dies ist der wichtigste Unterschied zwischen Delegierten und Ausdrücke. Rufen Sie
function
(aFunc<int, int, int>
), ohne jemals zu wissen, was Sie tun werden, mit der zwei Ganzzahlen übergeben. Es dauert zwei und gibt ein,, dass die meisten Ihren code wissen kann.Nun, im Gegensatz zu den Delegierten, Ihren code kann wissen, was ein Ausdruck Baum gemeint ist, zu tun.
Das bedeutet, dass Sie nicht nur berufen, ein Ausdruck, der Baum, wie man einen Delegaten aufrufen, aber Sie können es zu analysieren. Also, was können Sie Ihren code verstehen, durch die Analyse der variable
expression
?Hier sehen wir, dass es eine große Menge von Informationen, die wir bekommen können, die von einem Ausdruck.
Aber warum müssten wir das?
Wieder einmal sehen wir, dass der Ausdruck Bäume erlauben uns, Sie zu vertreten (express?) was wir machen wollen. Und wir verwenden die übersetzer, die sich dafür entscheiden wie unsere Ausdrücke sind gewöhnungsbedürftig.
Einen Ausdruck-Baum ist ein Mechanismus zu übersetzen ausführbaren code in Daten. Verwenden Sie einen Ausdruck-Baum, können Sie produzieren eine Datenstruktur, die für Ihr Programm.
In C# können Sie die Arbeit mit dem expression tree hergestellt von lambda-Ausdrücken mit der
Expression<T>
Klasse.In einem traditionellen Programm, schreiben Sie code wie diesen:
Dieser code bewirkt, dass der compiler generiert eine Belegung, und das ist es. In den meisten Fällen, das ist alles, die Sie interessieren.
Mit herkömmlichen Codes, Ihre Anwendung kann nicht rückwirkend zurück und betrachten Sie
hypotenuse
zu bestimmen, dass es produziert wurde, indem Sie eineMath.Sqrt()
nennen; diese information ist einfach nicht Teil dessen, was enthalten ist.Betrachten Sie jetzt ein lambda-Ausdruck wie den folgenden:
Dies ist ein wenig anders als zuvor. Jetzt
hypotenuse
ist eigentlich ein Verweis auf einen block von ausführbaren code. Wenn Sie anrufenerhalten Sie den Wert
5
zurückgegeben.Wir können Ausdruck Bäume zu erkunden, das blockieren von ausführbaren code, der produziert wurde. Versuchen Sie dies:
Diese produziert:
Mehr fortgeschrittene Techniken und Manipulationen möglich sind, mit Ausdruck Bäume.
Ausdruck Bäume sind eine in-memory-Repräsentation eines Ausdrucks, z.B. ein arithmetischer oder boolescher Ausdruck.
Betrachten Sie beispielsweise den arithmetischen Ausdruck
Da * eine höhere Rangfolge hat als +, der Ausdruck, der Baum ist gebaut wie die:
Unter diesem Baum, es kann ausgewertet werden, die für alle Werte von a und b.
Darüber hinaus können Sie wandeln Sie in andere Ausdruck Bäume, zum Beispiel zur Ableitung des Ausdrucks.
Beim implementieren Sie einen Ausdruck-Baum, würde ich vorschlagen, erstellen Sie eine base-Klasse
Ausdruck. Abgeleitet von der Klasse BinaryExpression würde verwendet werden für alle binäre Ausdrücke, wie z.B. + und * . Dann könnte man die Einführung einer VariableReferenceExpression auf Referenz-Variablen (z.B. a und b), und eine andere Klasse ConstantExpression (für die 2 aus dem Beispiel).
Den expression tree ist in vielen Fällen aufgebaut wie das Ergebnis der Analyse einer Eingabe (vom Benutzer direkt oder aus einer Datei).
Für die Bewertung der Ausdruck, der Baum, würde ich vorschlagen, verwenden Sie die Besucher-Muster.
Kurze Antwort:
Es ist schön, schreiben zu können, die die gleiche Art von LINQ-Abfrage und zeigen Sie es an einer beliebigen Datenquelle. Sie konnte nicht haben, eine "Sprache Integriert" - Abfrage, ohne es.
Lange Antwort:
Wie Sie wahrscheinlich wissen, ist beim kompilieren von source-code, Sie sind die Umwandlung von einer Sprache zur anderen. In der Regel aus einem high-level-Sprache (C#) zu einem unteren Hebel (IL).
Grundsätzlich gibt es zwei Möglichkeiten, wie Sie dies tun können:
Letzteres ist das, was alle Programme, die wir wissen, wie 'Compiler' zu tun.
Sobald Sie einen parse-Baum können Sie ganz einfach übersetzen Sie in jede andere Sprache und ist dieses, was Ausdruck Bäume, die uns erlauben zu tun. Da der code gespeichert wird als Daten, Sie können tun, was Sie wollen, aber wahrscheinlich werden Sie nur wollen, um es zu übersetzen in eine andere Sprache.
Nun, in LINQ to SQL-Ausdruck Bäume verwandelte sich in einen SQL-Befehl aus und wird dann über den Draht geschickt, um die Datenbank-server. Soweit ich weiß, Sie tun nichts wirklich Lust, bei der übersetzung der code, aber Sie könnte. Zum Beispiel, die Abfrage-Anbieter erstellen könnten verschiedene SQL-code, abhängig von der Netzwerk-Bedingungen.
IIUC, ein Ausdruck, der Baum ist ähnlich zu einem Abstrakten Syntax Baum, sondern ein Ausdruck der Regel yiels ein einzelner Wert, in der Erwägung, dass ein AST darstellen kann, ein ganzes Programm (mit Klassen, Pakete, Funktion, Aussagen, etc.)
Sowieso, für die einen der Ausdruck (2 + 3) * 5, der Baum:
Bewerten jeden Knoten rekursiv (bottom-up), um den Wert an der Wurzel-Knoten, d.h. der Wert des Ausdrucks.
Können Sie natürlich unäre - (negation) oder trinary (wenn-dann-sonst) - Operatoren zu, und die Funktionen (n-ary, dh eine beliebige Anzahl von ops), wenn Sie Ihre expression-language erlaubt es.
Bewertung der Arten und zu tun geben-die Steuerung erfolgt über ähnliche Bäume.
Der DLR
Ausdruck Bäume sind eine Ergänzung zu C# zu unterstützen, die Dynamic Language Runtime (DLR). Das DLR ist auch das, was ist verantwortlich für was uns die "var" - Methode: deklarieren von Variablen. (
var objA = new Tree();
)Mehr auf der DLR.
Im Grunde wollte Microsoft zu öffnen, die CLR, die für die dynamischen Sprachen wie LISP, SmallTalk, Javascript, etc. Zu tun, Sie mussten in der Lage sein, zu analysieren und auswerten von Ausdrücken zur Laufzeit. Das war nicht möglich, bevor der DLR kam.
Zurück zu meinem ersten Satz, Ausdruck Bäume sind eine Ergänzung zu C# eröffnet die Möglichkeit zur Nutzung des DLR. Vor diesem C# war eine sehr statische Sprache-alle Variablen-Typen musste erklärt werden, wie eine bestimmte Art und alle code geschrieben werden musste, zur compile-Zeit.
Es mit Daten
Ausdruck Bäumen öffnet die Schleusentore zu dynamischen code.
Sagen wir zum Beispiel, dass Sie die Schaffung einer Immobilien-Website. Während der design-phase, Sie kennen Sie alle Filter, die Sie anwenden können. Zu dieser code implementieren, haben Sie zwei Möglichkeiten: Sie können schreiben Sie eine Schleife, vergleicht jeder Datenpunkt ein, um eine Reihe von Wenn-Dann-Prüfungen; oder Sie können versuchen, eine Abfrage zu erstellen, die in einer dynamischen Sprache (SQL) und pass ein, aus, um ein Programm auszuführen, kann die Suche für Sie (die Datenbank).
Mit Expression trees, können Sie nun ändern Sie den code in Ihrem Programm-auf die fly-und die Suche durchführen. Speziell, Sie können dies tun, durch LINQ.
(Siehe: MSDN: gewusst Wie: Verwenden von Expression Trees zu Erstellen Dynamischer Abfragen).
Über Daten
Die wichtigsten Anwendungen für Expression-Bäume sind für die Verwaltung der Daten. Sie können jedoch auch verwendet werden, um dynamisch generierten code. Also, wenn Sie wollte, eine Funktion, die definiert wird dynamisch (ala Javascript), können Sie einen Ausdruck-Baum, kompilieren Sie es und bewerten die Ergebnisse.
Ich würde ein bisschen mehr gehen in die Tiefe, aber diese Seite ist viel besser:
Ausdruck Bäume als Compiler
Die aufgeführten Beispiele umfassen die Erstellung von generischen Operatoren für Variablen-Typen, die hand-Rollen lambda-Ausdrücke, Hochleistungs-flach Klonen und dynamisch kopieren Lesen/schreiben von Eigenschaften von einem Objekt zum anderen.
Zusammenfassung
Ausdruck Bäume sind Darstellungen von code, der kompiliert und zur Laufzeit ausgewertet. Sie ermöglichen eine dynamische Typen, die nützlich für Daten-manipulation und dynamische Programmierung.
var
ist eine Compilezeit-die syntaktische Zucker - es hat nichts zu tun mit dem Ausdruck, den Bäumen, dem DLR oder der Laufzeit.var i = 0
kompiliert wird, als wenn Sie schriebint i = 0
, so dass Sie nicht verwenden könnenvar
zu vertreten, eine Art, die nicht bekannt in der compile-Zeit. Ausdruck Bäume sind nicht "ein neben der Unterstützung des DLR", werden Sie eingeführt .NET 3.5, LINQ erlauben. DLR auf der anderen Seite eingeführt wird .NET 4.0 zu ermöglichen dynamischen Sprachen (wie IronRuby) und diedynamic
Schlüsselwort. Ausdruck Bäume von der DLR zu bieten interop, es ist nicht die andere Weise herum.Ist der Ausdruck der Struktur, in die Sie sich beziehen, ist Ausdruck Auswertung Baum?
Wenn ja, dann ist es Baum konstruiert durch den parser. Parser verwendet, der Lexer/Tokenizer zu identifizieren, die Spielmarken von dem Programm. Parser konstruiert der Binäre Baum aus der tokens.
Hier ist die ausführliche Erklärung