2017-01-19 4 views
2

Je viens d'apprendre à propos de Expression et de leurs arborescences d'expression pour les utiliser avec IronPython (mais ce n'est pas pertinent pour l'instant).Création d'une arborescence d'expression pour la concaténation de deux objets

Ce que je suis en train de faire est, la création d'un arbre d'expression comme le lambda suivant:

Func<T, int, string> func = (s,t) => s + t; 

Ma fonction actuelle est la suivante:

public static Expression<Func<T, int, string>> StringConcatSelector<T>() 
{ 
    var parameterParam = Expression.Parameter(typeof(T), "x"); 
    var paramToString = typeof(T).GetMethods().FirstOrDefault(s=>s.Name=="ToString"); 
    var parameter = Expression.Call(parameterParam, paramToString); 


    var intParameterParam = Expression.Parameter(typeof(int), "s"); 
    var intParameterToString = typeof(int).GetMethods().FirstOrDefault(s => s.Name == "ToString"); 
    var intParameter = Expression.Call(intParameterParam, intParameterToString); 

    var stringConcat = typeof(string).GetMethods().FirstOrDefault(s => s.Name == "Concat"); 

    var result = Expression.Call(stringConcat, parameter, intParameter); 

    return Expression.Lambda<Func<T, int, string>> 
         (result, parameterParam, intParameterParam); 
} 

le Expression.Call de String.Concat ne fonctionnera pas de cette façon, à cause d'un nombre de paramètres invalide. Je pense que je besoin de quelque chose comme:

  • créer un List<string> -variable expression
  • ajouter les deux valeurs à la liste
  • utilisation String.Concat avec la liste d'expression.

Ai-je raison?

Si oui, comment puis-je créer une variable de liste (ou un tableau), ajouter les deux valeurs pour le prendre comme paramètre pour mes String.Concat?

Répondre

4

String.Concat La méthode a 11 (!) Surcharges, et vous en prenez une aléatoire.

le plus approprié pour votre cas est

public static String Concat(String str0, String str1) 

que vous pouvez obtenir en utilisant la Type.GetMethod surcharge

public MethodInfo GetMethod(string name, Type[] types) 

où le tableau types représente le type des arguments de la méthode suivante:

var stringConcat = typeof(string).GetMethod("Concat", 
    new[] { typeof(string), typeof(string) }); 
+1

Oh. Oui. J'ai été sans tête à cela. Bien, cela fonctionne parfaitement :) –

+1

Vous pouvez également utiliser 'new [] {typeof (objet), typeof (objet)}' pour appeler la surcharge qui prend deux arguments 'object', et supprimer le besoin d'appeler' ToString() '. Avec le compilateur d'expressions interprétées, il serait probablement plus efficace, car il y a moins d'étapes pour l'interpréteur. Avec le compilateur IL, il serait probablement moins efficace ('int.ToString()' n'a pas besoin d'être encadré lorsqu'il est appelé directement, mais ce serait le cas), mais la simplification de l'expression en vaut probablement la peine. –

+0

@JonHanna merci pour votre indice, mais maintenant je reçois une exception. Il ne peut pas utiliser un objet de type Int32 en tant que paramètre de type Object. –