我试图在委托上绑定以下操作:
2*2+2
这当然应该给出6但我的例子给出了8
我认为这里使用的所有代表都不会被评估,直到这个linie
var result = response();
但它以其他方式工作,然后我被期待,我认为在响应变量委托下将是:
EvaluateConst()() * EvaluateConst()() + EvaluateConst()()
这种数学运算符的方式优先于语言规范,但不是。
static void Main(string[] args)
{
var response = Mul();
var result = response();
}
public static Func<double> Add()
{
return () => EvaluateConst()() + EvaluateConst()();
}
public static Func<double> Mul()
{
return () => EvaluateConst()() * Add()();
}
public static Func<double> EvaluateConst()
{
return () => 2;
}
有没有办法通过修改它来实现我想要的?
有趣的是,如果在行return () => 2;
上设置breakPoint
debuger只有在var result = response();
答案 0 :(得分:5)
你没有评估2 * 2 + 2.你正在评估
2 * (2 + 2)
代表参与的事实在这里是无关紧要的 - 无论如何,你总是在他们返回时对他们进行评估。您可以有效地将代码重写为:
static void Main(string[] args)
{
var result = Mul();
}
public static double Add()
{
return EvaluateConst() + EvaluateConst();
}
public static double Mul()
{
return EvaluateConst() * Add();
}
public static double EvaluateConst()
{
return 2;
}
首先要了解为什么 返回8,然后你可以回到你的委托版本。这是乘法运算的行:
return () => EvaluateConst()() * Add()();
当你调用EvaluateConst
时,会返回一个委托,当被调用时,它将返回2.
当你调用Add
时,它返回一个委托,当被调用时,它将返回4(通过自己调用EvaluateConst
并调用委托,执行两次,并将结果一起添加)
因此,您的lambda表达式将转换为委托,在调用时,它基本上会计算2 * 4.
如果你想评估2 * 2 + 2,你应该把它想象成这样:
+
* 2
2 2
换句话说:
static void Main(string[] args)
{
var response = Add();
var result = response();
}
public static Func<double> Add()
{
return () => Mul()() + EvaluateConst()();
}
public static Func<double> Mul()
{
return () => EvaluateConst()() * EvaluateConst()();
}
......但是,再次,代表方面的确是一个红色的鲱鱼。
答案 1 :(得分:0)
由于Add()()
是一个函数,因此必须在乘法发生之前评估其结果。这意味着您的函数Mul()
等同于:
public static Func<double> Mul()
{
return () => EvaluateConst()() * (EvaluateConst()() + EvaluateConst()());
}
与return 2 * (2 + 2)
答案 2 :(得分:0)
简单明白为什么......
首先,您要调用Mul
,这需要从EvaluateConst
和Add
获取两个运营商,因此它会调用EvaluateConst()
返回2,然后调用{{1} }返回4,2 * 4 = 8。
如果你没有使用代表
那就完全一样了Add
返回8.