具有可为Null小数和优先级为?的C#加法??操作人员

本文关键字:加法 操作 优先级 Null 小数 | 更新日期: 2023-09-27 18:22:11

假设一个C#程序具有两个可为null的十进制属性a和B。以下加法仅返回A的值:var结果=A??0+B??0;正确的用法是:var结果=(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
    }
}

我的问题是在计算结果1的过程中会发生什么。+和的优先级是多少??操作员

具有可为Null小数和优先级为?的C#加法??操作人员

tinstaafl的答案是正确的。对其进行扩展:

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

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

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

这不是你打算采取的行动;您可以使用(A ?? 0) + (B ?? 0)获得您想要的操作。相反,如果您的意思是"如果任一侧为空,则使用零",则可以使用(A + B) ?? 0。括号在后者中是不必要的,但考虑到您对+??的优先级感到困惑,这是一个好主意。

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

我认为更重要的是,你不应该把这件事留给任何人来解释,这是一个明确的例子,说明为了可读性和避免怀疑,你应该总是使用括号。维护是首要任务。