2013-07-14 22 views
5

假设C#程序具有两个可为空的小数属性A和B 下面此外返回一个唯一的值: VAR结果= A 10 0 + B? 0; 正确的用法是: var result =(A ?? 0)+(B ?? 0);C#加上可为空的小数和优先级为?操作者

样品控制台程序:

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在计算过程中会发生什么。 +和?的优先级如何?运营商?

回答

8

tinstaafl的答案是正确的。若要扩展它:

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

。因此A ?? 0 + B ?? 0的动作是:

  • 计算A,你状态是可空类型小数点。如果它非空,则获取其十进制值作为结果。我们现在已经完成了;从不计算B
  • 零已被编译器转换为十进制,并且对提升算术的空检查被取消。 (参见my series of articles on how nullable arithmetic is optimized by the compiler联系)
  • B被计算并检查空。如果它为空,则加法的结果为空;如果不是,则加法的结果是一个可为空的小数。
  • 添加的结果现在检查为空。如果它为空,则结果为零(再次,已经转换为十进制)。如果它不是null,那么它的值被提取并且变成结果。

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

+0

好的,谢谢你的正确回复 – FSou1

+0

当我们得到这种信息的时候,它非常棒 – 2013-07-15 04:48:58

+0

谢谢大家的回答和解释。 – Nicolo

2

没有()中的第一条语句,你告诉第一?如果A为空,则运算符返回0 + B,而第二个?运算符在B为空时返回0。因此+运营商正在使用?如果设置为null,它应该返回0.69

1

我觉得更重要的是,你不应该离开这个人的解释操作的语句只会返回A.,这是当你应该总是用一个明显的例子括号为可读性和避免疑问。维护是重中之重。

+1

事实上,除了最先被执行,那么第一个聚结,然后是第二聚结。所以'A? 0 + B? 0'相当于'A? (0 + B)?? 0',而不是'A? (0 + B?0)' –

+0

谢谢,我没有意识到这一点,我会编辑我的文章留下我的建议关于可读性。 – 2013-07-14 06:23:06

+0

@RobertHarvey:您的评论不正确。空合并是正确的联合和加法是更高的优先级,所以'A? 0 + B? 0','A? (0 + B)?? 0'和'A ?? (0 + B 0)'都等于'A?((0 + B)∞0)'。相同的东西在定义上相当于彼此;这就是“等价”的意思。 –

相关问题