C# 生成执行另一个表达式的表达式

C# 生成执行另一个表达式的表达式,c#,linq-expressions,C#,Linq Expressions,我想构建一个使用另一个表达式的表达式,这将给我一个漂亮的ToString()输出 用普通lambda表示,我想这样做: Func<string> extractFunc = () => "Marsh"; Func<bool> compareFunc = () => extractFunc() == "Mallow"; 我想要的是类似的东西: () => "March" == "Mallow" 我应该写什么来代替extractExp.Compile()

我想构建一个使用另一个表达式的表达式,这将给我一个漂亮的
ToString()
输出

用普通lambda表示,我想这样做:

Func<string> extractFunc = () => "Marsh";
Func<bool> compareFunc = () => extractFunc() == "Mallow";
我想要的是类似的东西:

() => "March" == "Mallow"
我应该写什么来代替
extractExp.Compile()()


(我可能不得不使用某种
ExpressionVisitor
来获得漂亮的输出。如果答案包括这一点,那就有好处了,但更重要的是如何将两个
表达式
合并起来。)

您在这里寻找的是一个
组合
方法,它可以接受一个表达式并将其映射到一个接受相同输入的方法,但对第一个函数的结果执行操作:

public static Expression<Func<TResult>>
    Compose<TIntermediate, TResult>(
    this Expression<Func<TIntermediate>> first,
    Expression<Func<TIntermediate, TResult>> second)
{
    return Expression.Lambda<Func<TResult>>(
        second.Body.Replace(second.Parameters[0], first.Body));
}
现在你可以写:

Expression<Func<string>> extractExp = () => "Marsh";
Expression<Func<bool>> compareExp = extractExp.Compose(s => s == "Mallow");
表达式extractExp=()=>“Marsh”;
表达式compareExp=extractExp.Compose(s=>s==“Mallow”);
public static Expression<Func<TResult>>
    Compose<TIntermediate, TResult>(
    this Expression<Func<TIntermediate>> first,
    Expression<Func<TIntermediate, TResult>> second)
{
    return Expression.Lambda<Func<TResult>>(
        second.Body.Replace(second.Parameters[0], first.Body));
}
internal class ReplaceVisitor : ExpressionVisitor
{
    private readonly Expression from, to;
    public ReplaceVisitor(Expression from, Expression to)
    {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
        return node == from ? to : base.Visit(node);
    }
}
public static Expression Replace(this Expression expression,
    Expression searchEx, Expression replaceEx)
{
    return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
Expression<Func<string>> extractExp = () => "Marsh";
Expression<Func<bool>> compareExp = extractExp.Compose(s => s == "Mallow");