I am currently trying to write some code which turns C# Expressions into text.
To do this, I need to not only walk through the Expression tree, but also evaluate just a little part of it - in order to get the current value of a local variable.
I am finding very hard to put into words, so here is the pseudo-code instead. The missing part is in the first method:
public class Program
{
private static void DumpExpression(Expression expression)
{
// how do I dump out here some text like:
// set T2 = Perform "ExternalCalc" on input.T1
// I can easily get to:
// set T2 = Perform "Invoke" on input.T1
// but how can I substitute Invoke with the runtime value "ExternalCalc"?
}
static void Main(string[] args)
{
var myEvaluator = new Evaluator() {Name = "ExternalCalc"};
Expression<Func<Input, Output>> myExpression = (input) => new Output() {T2 = myEvaluator.Invoke(input.T1)};
DumpExpression(myExpression);
}
}
class Evaluator
{
public string Name { get; set; }
public string Invoke(string input)
{
throw new NotImplementedException("Never intended to be implemented");
}
}
class Input
{
public string T1 { get; set; }
}
class Output
{
public string T2 { get; set; }
}
I have started investigating this using code like:
foreach (MemberAssignment memberAssignment in body.Bindings)
{
Console.WriteLine("assign to {0}", memberAssignment.Member);
Console.WriteLine("assign to {0}", memberAssignment.BindingType);
Console.WriteLine("assign to {0}", memberAssignment.Expression);
var expression = memberAssignment.Expression;
if (expression is MethodCallExpression)
{
var methodCall = expression as MethodCallExpression;
Console.WriteLine("METHOD CALL: " + methodCall.Method.Name);
Console.WriteLine("METHOD CALL: " + expression.Type.Name);
var target = methodCall.Object;
// ?
}
}
but once I get to that MethodCallExpression level then I am feeling a bit lost about how to parse it and to then get the actual instance.
Any pointers/suggestions on how to do this very much appreciated.
If I understand correctly, you're wondering how to get properties from the instance of the object the method in your example was being called on. As Marc mentions in his answer, expression trees are complex and time consuming to work with, this addresses specifically your example (and likely nothing else).
Parsing expression trees is... complex and time-consuming. Here's a very incomplete version that just-about handles your example. In particular, note that we need to:
Output:
Code: