Я пытаюсь изменить выражение функции. Я хочу заменить входной аргумент функции на функцию, которая возвращает то же значение. Идея состоит в том, чтобы преобразовать: function (Foo foo) { return foo.ToString(); }
с function(Func<Foo> fooProvider) { return fooProvider().ToString() }
На самом деле я даже не хочу вызывать переданную нам функцию, а напрямую использую тело функции. Таким образом, реальный пример не получает Func<Foo>
в качестве входных данных, а Expression<Func<Foo>>
.
Пример кода можно найти ниже. Я предполагаю, что получаю исключение сейчас, потому что я изменяю сигнатуру функции. Хотя это именно то, что я хочу сделать.
Какой-то код: Программа
class Program
{
public static void Run()
{
Expression<Func<int, bool>> isOdd = number => (number % 2) == 1;
Expression<Func<string, int>> parseTextToNumber = text => Convert.ToInt32(text);
var vistor = new ReplaceExpressionVisitor(isOdd.Parameters[0], parseTextToNumber.Body);
var result = vistor.Visit(isOdd);
Expression<Func<string, bool>> textRepresentsOddNumber = result as dynamic;
//Expected something like this:
Expression<Func<string, bool>> expectedResult = text => (Convert.ToInt32(text) % 2) == 1;
}
}
Класс посетителя
private class ReplaceExpressionVisitor : ExpressionVisitor
{
private readonly Expression _oldValue;
private readonly Expression _newValue;
public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
{
_oldValue = oldValue;
_newValue = newValue;
}
public override Expression Visit(Expression node)
{
if (node == _oldValue)
return _newValue;
return base.Visit(node);
}
}
И сообщение об ошибке:
System.InvalidOperationException: 'При вызове из' VisitLambda 'перезапись узла типа' System.Linq.Expressions.ParameterExpression 'должна возвращать ненулевое значение того же типа. Либо переопределите «VisitLambda» и измените его, чтобы не посещать детей этого типа. '