2009-09-10 10 views
16

Ich habe eine Funktion, die die folgende Signatur hat ...Konvertieren in Source Code-String einen Ausdruck Baum

public string DoJunk(Expression<Func<bool>> expression) 

Ich versuche, einen Weg zu finden, die „Ausdruck“ Parameter zurück zu so etwas wie das konvertieren Original-Quellcode (oder mindestens aC# -Darstellung des Original-Quellcodes). Also, wenn jemand ruft die Funktion wie folgt ...

DoJunk(() => (i + j) * 9 == Math.Round((double)j/(i - 3), 4)) 

... Ich möchte in der Lage sein, den Ausdruck, dies zu konvertieren ...

(i + j) * 9 == Math.Round((double)j/(i - 3), 4) 

Hat jemand dies getan?

+0

was ist der Kontext davon? –

+0

Ich experimentiere mit einigen Ideen für ein Unit-Testing-Framework. Meine Idee ist, dass, wenn Sie gegen ein Lambda testen und der Test fehlschlägt, Sie den Code zeigen könnten, der fehlgeschlagen ist. Zum Beispiel, statt "erwartet: 4 tatsächlich: 5", könnten Sie eine Nachricht mehr wie "erwartet: user.Age == 4 actual: user.Age == 5" – herbrandson

Antwort

8

Hier ist ein interessanter Artikel, mit Code, um die Umwandlung von Ausdrucksbäumen diskutieren zurück in etwas, das (in etwa) die ursprüngliche Quelle ähnelt:

Expression Trees-Lambdas to CodeDom Conversion

Als Randbemerkung, haben Sie haben versucht, die Methode ToString des Ausdrucks aufzurufen?

Expression<Func<int, int, bool>> expr = 
    (i, j) => (i + j) * 9 == Math.Round((double)j/(i - 3), 4); 

Console.WriteLine(expr.ToString()); 
// (i, j) => (Convert(((i + j) * 9)) = Round((Convert(j)/Convert((i - 3))), 4)) 

Console.WriteLine(expr.Body.ToString()); 
// (Convert(((i + j) * 9)) = Round((Convert(j)/Convert((i - 3))), 4)) 
+1

Ich habe versucht mit ToString(), aber es gibt mir etwas ziemlich eklig aussehen ... (Konvertieren ((Wert (LambdaToStringSpike.Program + <> c__DisplayClass0) .i + Wert (LambdaToStringSpike.Program + <> c__DisplayClass0) .j) * 9)) = Runde ((Convert (Wert (LambdaToStringSpike.Program + <> c__DisplayClass0) .j)/Convert ((Wert (LambdaToStringSpike.Program + <> c__DisplayClass0) .i - 3))), 4)) – herbrandson

+1

Ja, ich denke, die Ausgabe, die Sie sehen, ist was generiert wird hinter den Kulissen durch den C# -Compiler, um die erfassten Variablen "i" und "j" zu behandeln. In meinen Beispielen sind "i" und "j" Einheimische, daher ist die Ausgabe viel näher am ursprünglichen Quellcode. – LukeH

6

Ich bin gerade über das passiert; Ich habe eine kostenlose Open-Source-Bibliothek geschrieben, die eine Erweiterungsmethode stellt eine Quelle-Code-ähnliche Zeichenfolge aus einem Ausdruck zu erstellen:

using AgileObjects.ReadableExpressions; 

var myExpression = CreateBigExpressionTree(); 
var expressionSource = myExpression.ToReadableString(); 

ich a blog darüber geschrieben habe, ist die Quelle on GitHub, gibt es a NuGet package enthält eine Erweiterungsmethode, und ich habe eine Reihe von Debugger Visualizer für VS 10 - 17 geschrieben, die in the Visual Studio Marketplace sind.

Verwandte Themen