空合并操作顺序
本文关键字:顺序 操作 合并 | 更新日期: 2023-09-27 17:58:30
我从这个方法得到了奇怪的结果:
public static double YFromDepth(double Depth, double? StartDepth, double? PrintScale)
{
return (Depth - StartDepth ?? Globals.StartDepth) * PrintScale ?? Constants.YPixelsPerUnit ;
}
当我将null传递到StartDepth中时,合并失败了,因为"Depth-StartDepth"的计算方法似乎是先将StartDepth转换为默认值0(降级?),而不是先查看它是否为null并替换为Globals.StartDepth。
这是已知的事情吗?我可以通过添加括号来实现这一点,但我真的没想到事情会这样。
-
运算符的优先级高于??
,因此您的代码实际上是:
return ((Depth - StartDepth) ?? Globals.StartDepth) *
PrintScale ?? Constants.YPixelsPerUnit;
如果你不想要这个优先级,你应该明确地指定它:
return (Depth - (StartDepth ?? Globals.StartDepth)) *
PrintScale ?? Constants.YPixelsPerUnit;
就我个人而言,我会扩展方法以使其更清晰:
double actualStartDepth = StartDepth ?? Globals.StartDepth;
double actualScale = PrintScale ?? Constants.YPixelsPerUnit;
return (depth - actualStartDepth) * actualScale;
作为@Jon Skeet,这是一个优先级问题,可以通过用括号明确定义正确的优先级来解决。(例如(Depth - (StartDepth ?? Globals.StartDepth)) * PrintScale ?? Constants.YPixelsPerUnit;
)
这个概念并不明显,C#中优先级、关联性和评估顺序的工作方式并不总是直观的。
Eric Lippert在他的文章《先例与关联性与秩序》中很好地解释了这些概念。我强烈建议你读那篇文章。以下是最关键的摘录:
优先级
优先级规则描述了当表达式混合了不同类型的运算符时,应如何将括号不足的表达式加括号。例如,乘法的优先级高于加法,因此2+3 x 4等效于2+(3 x 4),而不是(2+3)x 4。
关联性
关联性规则描述了当表达式具有一组相同类型的运算符时,应如何将带括号不足的表达式加括号。例如,加法从左到右是关联的,因此a+b+c等价于(a+b)+c,而不是a+(b+c)。在普通算术中,这两个表达式总是给出相同的结果;在计算机算术中,它们不一定。(作为练习,你能找到a、b、c的值吗?这样(a+b)+c就等于c#中的a+(b+c)?)
评估顺序
求值顺序规则描述了表达式中每个操作数的求值顺序。括号只是描述了结果是如何组合在一起的;"先做括号"不是C#的规则。相反,C#中的规则是"严格从左到右计算每个子表达式"。
这完全取决于语言中设置的运算符优先级。IIRC?和具有相当低的优先级。
从不同运算符的优先级顺序可以看出,null合并比-
或*
低得多。
我认为括号有问题。。。。试试这个:
public static double YFromDepth(double Depth, double? StartDepth, double? PrintScale)
{
return (Depth - (StartDepth ?? Globals.StartDepth)) * (PrintScale ?? Constants.YPixelsPerUnit) ;
}
HTH