假设一个 C# 程序具有两个可为 null 的十进制属性 A 和 B。 以下添加仅返回 A 的值: var 结果 = A ?? 0 + B ?? 0; 正确的用法是: 变量结果 = (A ?? 0) + (B ?? 0);
示例控制台程序:
class Program
{
static void Main(string[] args)
{
A = (decimal)0.11;
B = (decimal)0.69;
NullableDecimalAddition();
Console.ReadLine();
}
public static decimal? A { get; set; }
public static decimal? B { get; set; }
private static void NullableDecimalAddition()
{
decimal result1 = A ?? 0 + B ?? 0;
decimal result2 = (A ?? 0) + (B ?? 0);
Console.WriteLine("result1: " + result1); // = 0.11
Console.WriteLine("result2: " + result2); // = 0.80
}
}
我的问题是result1 的计算过程中发生了什么。 + 和 ?? 的优先级如何?运营商?
最佳答案
tinstaafl 的回答是正确的。扩展它:
??
运算符是右结合 而+
运算符具有更高的优先级。因此 A ?? 0 + B ?? 0
等同于 A ?? ((0 + B) ?? 0)
,而不是 (A ?? 0) + (B ?? 0)
。
因此 A 的 Action ?? 0 + B ?? 0
是:
- Compute
A
,您声明它的类型可以为 nullable decimal。如果它是非空的,则获取其十进制值作为结果。我们现在完成了;B
永远不会被计算。 - 编译器已将零转换为十进制,并且省略了对提升算术的空检查。 (有关详细信息,请参阅 my series of articles on how nullable arithmetic is optimized by the compiler。)
- 计算 B 并检查其是否为空。如果为空则加法结果为空;如果不是,则加法的结果是一个可为空的小数。
- 现在检查加法结果是否为空。如果它为空,则结果为零(同样,已经转换为十进制)。如果它不为空,则获取它的值并成为结果。
这不是您想要的操作;你可以用 (A ?? 0) + (B ?? 0)
获得你想要的 Action 。相反,如果您打算表示“如果 任一侧 为 null,则使用零”,那么您可以使用 (A + B) ?? 0
。括号在后者中是不必要的,但考虑到您对 +
与 ??
的优先级感到困惑,这是一个好主意。
关于C# 添加可空小数和 ?? 的优先级运算符(operator),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17636820/