Expression Trees with dynamic parameter

.net c# c#-4.0 dynamic expression-trees

Question

This needs to be converted:

Func<dynamic, object> myFunc = t => return t.Name + " " + t.Surname;

into a tree of expressions.

What I came up with is as follows:

ParameterExpression target = ExpressionParameter(typeof(dynamic), "target");
ParameterExpression result = ExpressionParameter(typeof(object), "result");
BlockExpression block = Expression.Block(
     new [] { result },
     Expression.Assign(
           result,
           Expression.Add(
                 Expression.Add(
                      Expression.Property(target, "Name"),
                      Expression.Constant(" ", typeof(string))
                 ),
                 Expression.Property(target, "Surname")
           )
     )
);
Func<dynamic, object> myFunc = Expression.Lambda<dynamic, object>>(block, target).Compile();

The compiler, however, dislikestypeof(dynamic) and I kind of get it.dynamic is an example, not a type.object the essence.

I then went ahead and changed theParameterExpression :

ParameterExpression target = ExpressionParameter(typeof(object), "target");

Although the code now successfully builds, there is a runtime issue.

I'm attempting to determine the property's worth.Name of target , which may make sense if the itemdynamic .

but becausetarget is seen as a kindobject the Expression returns an error message informing meName is not a real property.

Is it possible to obtain a dynamic attribute using an expression?

1
8
4/29/2015 12:44:42 PM

Accepted Answer

For individuals who are or were seeking a remedy:

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();

Exactly what I'm doing is as follows:

  1. developed aCallSiteBinder that reveals the dynamic property's valueName with respect to the dynamic object supplied as argument
  2. developed aCallSiteBinder that reveals the dynamic property's valueSurname with respect to the dynamic object supplied as argument
  3. used the techniquestring.Concat(params object[] args) . I must do it by sending my justifications as an array ofobject . I'm making an array with these values:getName , " " , andgetSurname .

I referred to and utilized the following response as a guide:

Expression trees with C# 4's "oedynamic"

Using the method described above, one may carry out the following:

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 });
4
5/23/2017 12:17:34 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow