我有以下情况
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);
在我的情况下,我在某些字段中添加了调试快速监视表:
beleg.PreisDB == 8.39
beleg.PreisDB??0 == 8.39
beleg.PreisCouponDB == -0.49
beleg.PreisCouponDB??0 == -0.49
现在,QuickWatch也出现了奇怪的行为,当然还有结果
beleg.PreisDB??0 + beleg.PreisCouponDB??0 == 8.39
Math.Round(beleg.PreisDB??0 + beleg.PreisCouponDB??0, 2) == 8.39
gesamtPreis == 8.39
所以加8.39 + -0.49不会给我7.9而是8.39 这段代码在至少两个实例上运行了60万个案例,而我有这个行为,其他行为都很好。我现在看不见我的错误。问题是.net为什么会这样?我正在使用Visual Studio 2015和.net 4.5.2。
答案 0 :(得分: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));
}
}
另一种替代方法是使用Nullable<T>.GetValueOrDefault()
代替?? 0
:
Console.WriteLine(x.GetValueOrDefault() + y.GetValueOrDefault());
但是我想我可能会只使用带有方括号的版本-因此在您的情况下:
var gesamtPreis = Math.Round((beleg.PreisDB ?? 0) + (beleg.PreisCouponDB ?? 0), 2);
我肯定会像大多数其他运算符一样将空格放在??
中,否则,它会给您紧密绑定的印象(就像.
运算符一样)。
答案 1 :(得分:2)
var gesamtPreis = Math.Round(beleg.PreisDB??0 + beleg.PreisCouponDB??0, 2);
// Executed in this order
var gesamtPreis = Math.Round(beleg.PreisDB ?? ((0 + beleg.PreisCouponDB) ?? 0))
您的代码以不同的顺序执行。由于beleg.PreisDB
不是null
,因此永远不会添加beleg.PreisCouponDB
。尝试添加一些括号:
// Executed as you want it to be
var gesamtPreis = Math.Round((beleg.PreisDB ?? 0) + (beleg.PreisCouponDB ?? 0), 2);