Вместо использования ExpressionVisitor
вы можете создать фабрику Func
, например:
public static Expression<Func<TElement, bool>> ReplaceParameter<TElement>
(
Expression<Func<TElement, TElement, bool>> inputExpression,
TElement element
)
{
var inner = Expression.Lambda<Func<TElement, bool>>
(
inputExpression.Body,
inputExpression.Parameters[1]
);
var outer = Expression.Lambda<Func<TElement, Expression<Func<TElement, bool>>>>
(
inner,
inputExpression.Parameters[0]
);
var factory = outer.Compile();
return factory(element);
}
Чтобы сделать ее еще более полезной, вы можете сохранить factory
и вызывать ее каждый раз, когда захотитечтобы заменить параметр:
public static Func<TElement, Expression<Func<TElement, bool>>> CreateFactory<TElement>
(
Expression<Func<TElement, TElement, bool>> inputExpression
)
{
var inner = Expression.Lambda<Func<TElement, bool>>
(
inputExpression.Body,
inputExpression.Parameters[1]
);
var outer = Expression.Lambda<Func<TElement, Expression<Func<TElement, bool>>>>
(
inner,
inputExpression.Parameters[0]
);
return outer.Compile();
}
public static void Test()
{
var factory = CreateFactory<int>((i1, i2) => i1 > i2);
var greater5 = factory(5);
var greater2 = factory(2);
}
Что на самом деле здесь происходит?
Когда inputExpression
равно (i1, i2) => i1 > i2
, тогда inner
будет i1 => i1 > i2
, а outer
/ factory
будетi2 => i1 => i1 > i2
.