Arbres d’expression avec paramètre dynamic

Je veux convertir ceci:

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

Dans un arbre d’expression.

Ce que je suis venu avec, est ceci:

 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(ssortingng)) ), Expression.Property(target, "Surname") ) ) ); Func myFunc = Expression.Lambda>(block, target).Comstack(); 

Cependant, le compilateur n’aime pas le typeof(dynamic) et je le comprends bien. dynamic n’est pas un type, c’est un object par essence.

Alors j’ai procédé pour changer le ParameterExpression :

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

Le code est maintenant compilé, mais il y a un problème au moment de l’exécution.

J’essaie d’obtenir la valeur de la propriété Name de la target , ce qui peut avoir un sens si l’object était dynamic .

Mais puisque la target est considérée comme étant de type object , l’expression exprime une erreur en me disant que le Name n’existe pas en tant que propriété.

Existe-t-il une expression permettant d’extraire une propriété dynamic?

Pour ceux qui sont ou étaient intéressés par une 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(ssortingng).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 myFunc = Expression.Lambda>(block, target).Comstack(); 

Voici exactement ce que je fais:

  1. Création d’un CallSiteBinder qui obtient la valeur de la propriété dynamic Name de l’object dynamic transmis en argument
  2. Création d’un CallSiteBinder qui obtient la valeur de la propriété dynamic Surname de Surname de l’object dynamic transmis en argument
  3. Appelé la méthode ssortingng.Concat(params object[] args) . Pour cela, je dois envoyer mes arguments sous forme de tableau d’ object . Je crée le tableau avec les valeurs de getName , " " et getSurname .

J’ai utilisé la réponse suivante comme guide et référence:

C # 4 “dynamic” dans les arbres d’expression

Avec l’approche ci-dessus, on pourrait faire quelque chose comme ceci:

 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: //ssortingng.Concat(new object[] { person.Name, " ", person.Surname });