我正在尝试使用构建表达式求值程序 Linq表达。我试图这样做 所有函数参数都是惰性求值,但不能完全 到那儿。
我在写psuedo,但真实的是 linq表达。
示例表达式:
Func1(Func2(10) + 1, Func3(10))
更新
Expression.Call(Func1,
Expression.Add(
Expression.Call(Func2, Expression.Constant(10)),
Expression.Constant(1))
Expression.Call(Func3, Expression.Constant(10))
)
我希望在调用时评估Func1的参数 这就是我希望参数被惰性评估。包装时它是可行的 lambda表达式中的参数表达式,但如果我这样做二进制表达式 Func2(10)+ 1将失败,因为无法将lambda添加到常量表达式。
实际的功能代码如下所示:
int Func1(Func<int> arg1, Func<int> arg2)
{
}
运行时arg1将评估“Func2(10)+ 1”
运行时arg2将评估“Func3(10)”
所以在这里我可以选择是否要评估参数,以获得懒惰效果。
这有可能实现吗?
答案 0 :(得分:3)
首先,我认为在不使用表达式树的情况下首先讨论问题会很有帮助。你说这是你要打电话的功能:
int Func1(Func<int> arg1, Func<int> arg2)
{
}
您想了解如何使用表达式树实现以下内容吗?
Func1(() => Func2(10) + 1, () => Func3(10));
到目前为止这是正确的吗?如果这是真的,那么请考虑这个类:
class Program
{
public static void Main(string[] args)
{
Console.WriteLine(Func1(() => Func2(10) + 1, () => Func3(10)));
var arg1 = Expression.Add(Expression.Call(typeof(Program), "Func2", Type.EmptyTypes, Expression.Constant(10)), Expression.Constant(1));
var arg2 = Expression.Call(typeof(Program), "Func3", Type.EmptyTypes, Expression.Constant(10));
var callFunc1 = Expression.Call(typeof(Program), "Func1", Type.EmptyTypes, Expression.Lambda<Func<int>>(arg1), Expression.Lambda<Func<int>>(arg2));
var tester = Expression.Lambda<Func<int>>(callFunc1);
int result = tester.Compile()();
Console.WriteLine(result);
}
static int Func1(Func<int> arg1, Func<int> arg2)
{
return arg1() + arg2();
}
static int Func2(int arg)
{
return arg;
}
static int Func3(int arg)
{
return 2 * arg;
}
}
它会打印31
两次:(10 + 1) + (10 * 2)
。第一个是直接调用它,第二个是使用表达式树。