I want to convert this:
Func myFunc = t => return t.Name + \" \" + t.Surname;
Into an Expression Tree.
What I
For those who are or were interested in a solution:
ParameterExpression target = Expression.Parameter(typeof(object), "target");
ParameterExpression result = Expression.Parameter(typeof(object), "result");
CallSiteBinder getName = Binder.GetMember(
CSharpBinderFlags.None, "Name", typeof(Program),
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
}
);
CallSiteBinder getSurname= Binder.GetMember(
CSharpBinderFlags.None, "Surname", typeof(Program),
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
}
);
BlockExpression block = Expression.Block(
new[] { result },
Expression.Assign(
result,
Expression.Call(typeof(string).GetMethod("Concat", new Type[] { typeof(object[]) }),
Expression.NewArrayInit(typeof(object),
Expression.Dynamic(getName, typeof(object), target),
Expression.Constant(" ", typeof(object)),
Expression.Dynamic(getSurname, typeof(object), target)
)
)
)
);
Func<dynamic, object> myFunc = Expression.Lambda<Func<dynamic, object>>(block, target).Compile();
Here's exactly what I am doing:
CallSiteBinder
that obtains the value of the dynamic property Name
of the dynamic object passed as argumentCallSiteBinder
that obtains the value of the dynamic property Surname
of the dynamic object passed as argumentstring.Concat(params object[] args)
. For that, I need to send my arguments as an array of object
. I'm creating the array with the values of getName
, " "
, and getSurname
.I used the following answer as a guide and reference:
C# 4 “dynamic” in expression trees
With the above approach, one could do something like this:
dynamic person = new ExpandoObject();
person.Name = "Matt";
person.Surname = "Smith";
object value = myFunc(person);
Console.WriteLine(value); //Will print out "Matt Smith"
//Internally it just calls:
//string.Concat(new object[] { person.Name, " ", person.Surname });