Я только что узнал о 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
?
Ох. Да. Я был безголовый. Отлично, он отлично работает :) –
В качестве альтернативы вы можете использовать 'new [] {typeof (object), typeof (object)}' для вызова перегрузки, которая принимает два аргумента 'object' и устраняет необходимость вызова' ToString() '. С интерпретируемым компилятором выражения, который также, вероятно, будет более эффективным, поскольку для интерпретатора будет меньше шагов. С ИЛ-компиляцией он, вероятно, будет немного менее эффективным ('int.ToString()' не нужно вводить при вызове напрямую, но это будет полем), но упрощение выражения, вероятно, по-прежнему стоит того. –
@JonHanna спасибо за ваш намек, но теперь я получаю исключение. Он не может использовать объект из типа Int32 в качестве параметра из типа Object. –