C# 返回其他代理的组合
我需要返回另外两个表达式的乘法表达式,但这个例子给了我错误C# 返回其他代理的组合,c#,C#,我需要返回另外两个表达式的乘法表达式,但这个例子给了我错误 public Func<double> EvaluateOne() { return () => EvaluateTwo() * EvaluateTwo(); } public Func<double> EvaluateTwo() { return () => 2; } public Func EvaluateOne() { return()=>EvaluateTwo()*Eval
public Func<double> EvaluateOne()
{
return () => EvaluateTwo() * EvaluateTwo();
}
public Func<double> EvaluateTwo()
{
return () => 2;
}
public Func EvaluateOne()
{
return()=>EvaluateTwo()*EvaluateTwo();
}
公共职能评估wo()
{
返回()=>2;
}
在函数EvaluateOne中
错误:
无法将操作数*应用于Func和Func
类型的操作数,这是因为调用EvaluateTwo()
返回的是Func
,而不是值2
您可以通过以下方式解决此问题:
public Func<double> EvaluateOne()
{
var eval2 = EvaluateTwo();
return () => eval2() * eval2();
}
public Func EvaluateOne()
{
var eval2=EvaluateTwo();
return()=>eval2()*eval2();
}
注意:@Blorgbeard的答案没有此答案中的方法所具有的弱点。如果调用
EvaluateTwo()
会在每次调用时返回不同的Func
实例,则此答案将导致错误的结果。不能将两个Func
对象相乘,但可以将计算结果相乘
return () => EvaluateTwo()() * EvaluateTwo()();
通过这种方式,您可以同时获得优化和延迟计算。您也可以使用表达式树来实现这一点,它允许您递归地创建一个大小不断增加的表达式,而无需计算任何内容:
using NumFunc = System.Func<double>;
using NumExpr = System.Linq.Expressions.Expression<System.Func<double>>;
...
static NumExpr Square(NumExpr operand)
{
return Product(operand, operand);
}
static NumExpr Product(NumExpr left, NumExpr right)
{
return Expression.Lambda<NumFunc>(Expression.Multiply(left.Body, right.Body));
}
您可以在这里看到一个演示:
return()=>EvaluateTwo()()*EvaluateTwo()代码>天哪,看起来不错,请把这个复制到answr中,我会接受它。@kosnkov你想在这里实现什么?这看起来像是XY问题。如果您正在编写解析器,您可能需要查看AntlR。这只是本特定示例中的情况,如果EvaluateTwo()
是一个生成器,这将导致错误的结果。顺便说一句,我的答案也是如此。第二组()
来自于使用局部变量。
using NumFunc = System.Func<double>;
using NumExpr = System.Linq.Expressions.Expression<System.Func<double>>;
...
static NumExpr Square(NumExpr operand)
{
return Product(operand, operand);
}
static NumExpr Product(NumExpr left, NumExpr right)
{
return Expression.Lambda<NumFunc>(Expression.Multiply(left.Body, right.Body));
}
var result1 = Product(() => 2, () => 3);
var result2 = Product(result1, () => 5);
var result3 = Square(result2);
// Nothing has been computed so far!
Console.WriteLine("{0}={1}", result3.Body, result3.Compile().Invoke());
// Output: (((2 * 3) * 5) * ((2 * 3) * 5))=900