2017-01-19 8 views
2

Я только что узнал о Expression и их деревьях выражений, чтобы использовать их с IronPython (но на данный момент это не имеет значения).Создание дерева выражений для объединения строк двух объектов

То, что я пытаюсь сделать это, создавая дерево выражения вроде следующего лямбда:

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

Моя текущая функция заключается в следующем:

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

Expression.Call из String.Concat не будет работать таким образом, из-за недопустимого значения параметра. Так что я думаю, что нужно что-то вроде:

  • создать List<string> -переменную-выражение
  • добавить оба значения в список
  • использования String.Concat со списком экспрессией.

Я прав?

Если да, то как я могу создать переменную List (или массив), добавьте оба значения, чтобы принять их как параметр для моего String.Concat?

ответ

4

String.Concat метод имеет 11 (!) Перегрузок, и вы принимаете случайный.

Наиболее подходящий для Вашего случая является

public static String Concat(String str0, String str1) 

, который вы можете получить с помощью следующей Type.GetMethod перегрузки

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

где types массив представляет собой тип аргументов метода:

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

Ох. Да. Я был безголовый. Отлично, он отлично работает :) –

+1

В качестве альтернативы вы можете использовать 'new [] {typeof (object), typeof (object)}' для вызова перегрузки, которая принимает два аргумента 'object' и устраняет необходимость вызова' ToString() '. С интерпретируемым компилятором выражения, который также, вероятно, будет более эффективным, поскольку для интерпретатора будет меньше шагов. С ИЛ-компиляцией он, вероятно, будет немного менее эффективным ('int.ToString()' не нужно вводить при вызове напрямую, но это будет полем), но упрощение выражения, вероятно, по-прежнему стоит того. –

+0

@JonHanna спасибо за ваш намек, но теперь я получаю исключение. Он не может использовать объект из типа Int32 в качестве параметра из типа Object. –

Смежные вопросы