2016-04-05 9 views
1

Ich versuche, einen Teil eines Ausdrucks Baum zu ändern, in dem eine Eigenschaft X vom Typ MyEnum auf einen Wert x verglichen wird:Rewritten Ausdruck ruft Operator Methode ... aber der ursprüngliche Knoten hatte keine Operator-Methode

$model.X == .Constant<MyEnum>(x) 

Ich möchte den Baum ändern, um den Vergleich zu ersetzen, um eine Eigenschaft Y des Typs Guid mit einem Wert y zu vergleichen (der von x abgeleitet wird).

$model.Y == .Constant<Guid>(y) 

So habe ich von ExpressionVisitor geerbt und ich habe VisitMember überschrieben Y für X zu ersetzen, und ich habe VisitConstant überschrieben y für x zu ersetzen.

das Lauf ergibt folgende InvalidOperationException:

System.InvalidOperationException: Rewritten Ausdruck ruft Operator Methode 'Boolean op_Equality (System.Guid, System.Guid)', aber der ursprüngliche Knoten hatte keine Operator-Methode. Wenn dies beabsichtigt ist, überschreiben Sie 'VisitBinary' und ändern Sie es, um das Neuschreiben zu ermöglichen.

Meine Hauptfrage ist: Was muss ich in VisitBinary tun? Und meine Nebenfrage ist: Warum gibt die Exception-Nachricht an, dass der ursprüngliche Knoten keine Operator-Methode hatte. Ich denke, das ist nicht wahr. Es hatte nicht op_Equality(System.Guid, System.Guid) sicher, aber es hatte den Gleichheitsoperator für den MyEnum-Typ, nehme ich an.

Antwort

3

Ich rate von dem Namen, dass MyEnum eine Art von Enum Typ ist.

Enum Typen benötigen keine Operatormethoden, da CIL Gleichheitsvergleiche für sie direkt behandelt (dasselbe gilt auch für die eingebauten Integral-, Gleitkomma- und Booleschen Typen).

Es gibt keine Möglichkeit, die Methode durch BinaryExression.Update() zu ändern (die entweder explizit in Ihrem Besucher oder implizit aufgerufen wird, weil Ihr Besucher einen oder beide der linken und rechten Ausdrücke geändert hat, und das ist in diesem Fall das Standardverhalten) muss VisitBinary() erstellen und einen neuen BinaryExpression durch den entsprechenden Aufruf an Expression.Equal() zurückgeben.

+0

Overriding VisitBinary ist in jedem Fall die bessere Wahl, weil es die gesamte Logik an einem Ort vereint. Ich frage mich, wie der OPs-Code aussehen muss, bevor er das tut, wahrscheinlich mit dem Instanzstatus, der über VisitC-Aufrufe übertragen wird. In VisitBinary kann er einfach die zwei Kinder untersuchen und, wenn sie übereinstimmen, die Neuschreibung durchführen. +1 – usr

+0

Das ist eine sehr interessante Erkenntnis. Ich wusste nicht, dass die Expression-Klassen bereits CIL-Kenntnisse beinhalten, noch bevor sie kompiliert werden. – Dejan

+0

Es ist mehr die Factory-Methode als die Instanz selbst. Es ist erwähnenswert, dass, wenn Sie mit einem binären Ausdruck mit einer anderen Operatormethode gestartet hätten, die Aktualisierung immer noch fehlgeschlagen wäre, aber mit einer anderen Ausnahme, so dass die Implementierungsdetails die Art der Ausnahme beeinflussen (was vielleicht immer noch nicht ideal ist) nicht, ob es passiert. –

Verwandte Themen