C#.net中的添加在某些情况下不起作用

Lar*_*ars 5 .net c#

我有以下案例

beleg.PreisDB = (double?)orders.Where(x => x.orderId == beleg.auftrnr).Sum(x => x.itemPrice + x.shippingPrice + x.giftWrapPrice) ?? 0;
beleg.PreisCouponDB = (double?)orders.Where(x => x.orderId == beleg.auftrnr).Sum(x => x.itemPromotionDiscount + x.shipPromotionDiscount) ?? 0;
var gesamtPreis = Math.Round(beleg.PreisDB??0 + beleg.PreisCouponDB??0, 2);
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我在调试中添加了一个quickwatch到一些字段:

beleg.PreisDB == 8.39
beleg.PreisDB??0 == 8.39
beleg.PreisCouponDB == -0.49
beleg.PreisCouponDB??0 == -0.49
Run Code Online (Sandbox Code Playgroud)

而现在奇怪的行为也来自快速观察,当然还有结果

beleg.PreisDB??0 + beleg.PreisCouponDB??0 == 8.39
Math.Round(beleg.PreisDB??0 + beleg.PreisCouponDB??0, 2) == 8.39
gesamtPreis == 8.39
Run Code Online (Sandbox Code Playgroud)

所以添加8.39 + -0.49并没有给我7.9但是8.39这个代码在至少有两个600k的情况下运行我有这种行为,其他人表现得很好.我现在不敢看到我的错误.问题是为什么.net表现得像这样?我正在使用Visual Studio 2015和.net 4.5.2.

Jon*_*eet 12

问题是优先级 - +具有更高的优先级??,因此它"更紧密".

这是一个完整的示例来演示:

using System;

class Test
{
    static void Main()
    {
        double? x = 8.39;
        double? y = -0.49;

        // Your expression
        Console.WriteLine(x ?? 0 + y ?? 0);

        // The equivalent you're expecting
        Console.WriteLine((x ?? 0) + (y ?? 0));

        // The actual bracketing
        Console.WriteLine(x ?? ((0 + y) ?? 0));
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用Nullable<T>.GetValueOrDefault()而不是?? 0:

Console.WriteLine(x.GetValueOrDefault() + y.GetValueOrDefault());
Run Code Online (Sandbox Code Playgroud)

但我想我可能只是使用带括号的版本 - 所以在你的情况下:

var gesamtPreis = Math.Round((beleg.PreisDB ?? 0) + (beleg.PreisCouponDB ?? 0), 2);
Run Code Online (Sandbox Code Playgroud)

我肯定会??像大多数其他操作符一样将空格放在圆形中,否则它会给你非常紧密的绑定印象(就像.操作符一样).

  • 显然Coverity已经删除了我在2013年写的关于这个问题的文章.Vexing!我会看看我是否可以将其从机器中取出并重新发布. (2认同)
  • @EricLippert:我可以解释为什么我*写*它是`x ??(0+(y ?? 0))` - 我不够小心:)现在修复了.我认为.但也许不是 - 我也需要检查关联性. (2认同)
  • 当然````运算符要求它的左边是可空的,所以`1 ?? what`不是合法的代码.但更重要的是重要的; `??`运算符被定义为无条件地计算其左操作数并有条件地评估其右操作数. (2认同)