5

假设一个 C# 程序具有两个可以为空的十进制属性 A 和 B。以下加法仅返回 A 的值: var result = A ?? 0 + B ?? 0; 正确的用法是: var result = (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 进行计算期间会发生什么。+ 和 ? 的优先级如何?运营商?

4

3 回答 3

8

tinstaafl 的回答是正确的。扩展它:

??运算符是右结合运算符,+运算符具有更高的优先级。因此A ?? 0 + B ?? 0等于A ?? ((0 + B) ?? 0),不是(A ?? 0) + (B ?? 0)

因此 的作用A ?? 0 + B ?? 0是:

  • 您声明的ComputeA是可为空的十进制类型。如果不为空,则获取其十进制值作为结果。我们现在完成了;B从不计算。
  • 编译器已经将零转换为十进制,并且省略了对提升算术的空检查。(有关详细信息,请参阅我关于编译器如何优化可空运算的系列文章。)
  • B 被计算并检查是否为空。如果为null,则加法的结果为null;如果不是,那么加法的结果是一个可以为空的小数。
  • 现在检查加法的结果是否为空。如果它为空,则结果为零(同样,已转换为十进制)。如果它不为空,则获取其值并成为结果。

这不是您打算采取的行动;您可以使用(A ?? 0) + (B ?? 0). 如果您打算相反地表示“如果任一侧为空,则使用零”,那么您可以使用(A + B) ?? 0. +括号在后者中是不必要的,但考虑到您对vs的优先级感到困惑,这是一个好主意??

于 2013-07-14T14:49:27.363 回答
2

在第一个语句中没有 (),你说的是第一个 ?? 如果 A 为空,则运算符返回 0 + B,第二个 ?? 如果 B 为空,则运算符返回 0。因此,由于 ?? 正在使用 + 运算符 运算符该语句将仅返回 A。如果将 A 设置为 null,则应返回 .69

于 2013-07-14T05:51:49.807 回答
1

我认为更重要的是,您不应该将其留给任何人来解释,这是一个明显的例子,说明何时应该始终使用括号来提高可读性和避免疑问。维护是重中之重。

于 2013-07-14T05:53:09.953 回答