Expression Trees with dynamic parameter

前端 未结 1 1958
孤街浪徒
孤街浪徒 2021-02-03 13:33

I want to convert this:

Func myFunc = t => return t.Name + \" \" + t.Surname;

Into an Expression Tree.

What I

相关标签:
1条回答
  • 2021-02-03 13:50

    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:

    1. Created a CallSiteBinder that obtains the value of the dynamic property Name of the dynamic object passed as argument
    2. Created a CallSiteBinder that obtains the value of the dynamic property Surname of the dynamic object passed as argument
    3. Invoked the method string.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 });
    
    0 讨论(0)
提交回复
热议问题