委托评估订单

时间:2015-04-30 13:54:49

标签: c#

我试图在委托上绑定以下操作: 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();

中进行finall评估后才会抓住它

3 个答案:

答案 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,这需要从EvaluateConstAdd获取两个运营商,因此它会调用EvaluateConst()返回2,然后调用{{1} }返回4,2 * 4 = 8。

如果你没有使用代表

那就完全一样了
Add

返回8.