C#添加可空小数和优先级??操作者

时间:2013-07-14 05:35:29

标签: c# decimal nullable addition

假设一个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进行计算时会发生什么。 +和??的优先级如何?运营商吗

3 个答案:

答案 0 :(得分:8)

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

??运算符是右关联+运算符的优先级更高。因此,A ?? 0 + B ?? 0相当于A ?? ((0 + B) ?? 0),而不是(A ?? 0) + (B ?? 0)

因此A ?? 0 + B ?? 0的行动是:

  • 计算A,您声明的类型为可为空的十进制。如果它为非null,则获取其十进制值作为结果。我们现在完成了;永远不会计算B
  • 编译器已经将零转换为十进制,并且省略了对提升算术的空检查。 (有关详细信息,请参阅my series of articles on how nullable arithmetic is optimized by the compiler。)
  • 计算
  • B并检查空值。如果为null,则加法结果为null;如果没有,则添加的结果是可以为空的小数。
  • 现在检查添加的结果是否为空。如果为null,则结果为零(同样,已经转换为十进制)。如果它不为null,则获取其值,结果为。

这不是你想要的行动;您可以使用(A ?? 0) + (B ?? 0)获取预期的操作。如果您的意图相反意味着“如果任何一方使用零为空”,那么您可以使用(A + B) ?? 0。后者中的括号是不必要的,但鉴于您对+ vs ??的优先级感到困惑,这是一个好主意。

答案 1 :(得分:2)

在第一个语句中没有(),你会告诉第一个?如果A为空,则运算符返回0 + B,第二个??如果B为null,则运算符返回0。因此,+运算符正被??运算符语句只返回A.如果将A设置为null,则应返回.69

答案 2 :(得分:1)

我认为更重要的是,你不应该把它留给任何人的解释,这是一个明显的例子,你应该总是使用括号来提高可读性和避免怀疑。维护是一个优先事项。