Das Objekt aus einem MemberExpression holen?

c# expression-trees lambda

Frage

Also, sagen wir, ich habe den folgenden Ausdruck in C #:

Expression<Func<string>> expr = () => foo.Bar;

Wie ziehe ich einen Verweis auf foo?

Akzeptierte Antwort

Expression<Func<string>> expr = () => foo.Bar;
var me = (MemberExpression)((MemberExpression)expr.Body).Expression;
var ce = (ConstantExpression)me.Expression;
var fieldInfo = ce.Value.GetType().GetField(me.Member.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var value = (Foo)fieldInfo.GetValue(ce.Value);

Beliebte Antwort

Ich hatte das gleiche Problem, aber etwas komplizierter, und Darin Dimitrovs Antwort gab mir einen guten Start. Ich werde meine Ergebnisse hier veröffentlichen, trotz der Tatsache, dass dies eine "alte" Frage ist.


Fall 1: Das Stammobjekt ist ein Objektelement

    this.textBox.Text    // where 'this' has type 'Form'

... entspricht dem folgenden Ausdrucksbaum:

    this.textBox.Text    // where 'this' has type 'Form'

Die einzige Stelle in diesem Ausdrucksbaum, an der Sie tatsächlich eine Objektreferenz erhalten, stammt aus der ConstantExpression : Sie können einen Verweis this . Die Grundidee, einen Objektverweis in diesem Baum zu erhalten, lautet daher:

  1. .Expression Sie in den Ausdrucksbaum entlang der .Expression Achsen, bis Sie einen ConstantExpression Knoten erreichen.

  2. .Value Eigenschaft .Value dieses Knotens. Dies ist das Wurzelobjekt Referenz (dh. this in dem obigen Beispiel).

  3. Mit reflection und den MemberInfo Knoten aus der Ausdrucksbaumstruktur erhalten Sie Objektreferenzen und arbeiten sich den Ausdrucksbaum hoch.

Hier ist ein Code, der dies veranschaulicht:

    this.textBox.Text    // where 'this' has type 'Form'

Fall 2: Das Stammobjekt ist ein statisches Klassenmitglied

    this.textBox.Text    // where 'this' has type 'Form'

... führt zu einem anderen Ausdrucksbaum. Hinweis zur Nullreferenz unten links:

    this.textBox.Text    // where 'this' has type 'Form'

Hier können Sie die Phase "Abstieg" nicht stoppen, indem Sie auf einen ConstantExpression Ausdruck warten. Stattdessen hören Sie auf, abzusteigen, wenn Sie eine Nullreferenz erreichen. Als Nächstes rufen Sie den Stammobjektverweis wie folgt ab:

    this.textBox.Text    // where 'this' has type 'Form'

Die "Aufstieg" -Phase von dort an ist die gleiche wie zuvor.


Es gibt sicherlich mehr Fälle (wie named-Parameter als das Root-Objekt), aber ich hoffe, dass ich die Grundidee inzwischen durchgezogen habe, also werde ich hier abschneiden.




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