gpt4 book ai didi

c# - 在编译器生成的表达式树中使用表达式

转载 作者:太空狗 更新时间:2023-10-29 22:30:54 25 4
gpt4 key购买 nike

我知道我可以使用以下方法创建表达式树:

  1. 工厂方法。

  2. 将 lambda 表达式编译器转换为 Expression

对于复杂的表达式树,我更喜欢 2,因为它更简洁。

是否可以使用这种方式引用已经构建的表达式

using System;
using System.Linq.Expressions;

public class Test
{
public static Expression<Func<int, int>> Add(Expression expr)
{
#if false
// works
ParameterExpression i = Expression.Parameter(typeof(int));
return Expression.Lambda<Func<int, int>>(Expression.Add(i, expr), i);
#else
// compiler error, can I pass expr here somehow?
return i => i + expr;
#endif
}

public static void Main()
{
Func<int, int> f = Add(Expression.Constant(42)).Compile();
Console.WriteLine(f(1));
}
}

最佳答案

没有任何现成的东西,但您可以自己构建一个工具来提供此功能。

您可以编写一个接受具有两个参数的表达式的方法,一个是“真实”参数,另一个是您要用另一个表达式的值替换的某个值的参数。然后,您可以使用一个解析为该值的表达式,并将该参数的所有实例替换为第二个表达式:

public static Expression<Func<TSource, TResult>> BuildExpression
<TSource, TOther, TResult>(
Expression<Func<TSource, TOther, TResult>> function,
Expression<Func<TOther>> innerExpression)
{
var body = function.Body.Replace(function.Parameters[1], innerExpression.Body);
return Expression.Lambda<Func<TSource, TResult>>(body, function.Parameters[0]);
}

您可以使用以下方法将一个表达式的所有实例替换为另一个表达式:

public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
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<Func<int, int>> Add(Expression<Func<int>> expr)
{
return BuildExpression((int i, int n) => i + n, expr);
}

关于c# - 在编译器生成的表达式树中使用表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26999406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com