一道數學運算題


事由是同事在工作中遇到的一個小問題,然后發到群里大家研究出來原因到底在哪里,問題是這樣的:

int? a = 2;
int? b = 1;
var res1= ((a ?? 0) + (b ?? 0)); 
var res2 = (a ?? 0 + b ?? 0); 

 

求res1,res2的值?

我相信,大部分程序員都會有這樣的答案,都會說3,但是知道肯定不會都是3這么簡單的,於是我把它封裝成一個類里的兩個方法。

public class Class1
    {
        public void A()
        {
            int? a = 2;
            int? b = 1;
            var res1 = ((a ?? 0) + (b ?? 0));
        }
        public void B()
        {
            int? a = 2;
            int? b = 1;
            var res2 = (a ?? 0 + b ?? 0);
        }
    }

 

使用反編譯神器Reflector反編譯來查看究竟。

public void A()
{
    int? a = 2;
    int? b = 1;
    int? CS$0$0000 = a;
    CS$0$0000 = b;
    int res1 = (CS$0$0000.HasValue ? CS$0$0000.GetValueOrDefault() : 0) + (CS$0$0000.HasValue ? CS$0$0000.GetValueOrDefault() : 0);
}

public void B()
{
    int? CS$0$0001;
    int? a = 2;
    int? b = 1;
    int? CS$0$0000 = a;
    int res2 = CS$0$0000.HasValue ? CS$0$0000.GetValueOrDefault() : (((CS$0$0001 = b) = CS$0$0001.HasValue ? new int?(CS$0$0001.GetValueOrDefault()) : null).HasValue ? CS$0$0001.GetValueOrDefault() : 0);
}

 

      從反編譯出來的代碼可以很清楚的看到,方法A很好的遵循了我們想象中的一般運算的順序,也是括號起到的應有作用,先算左邊,再算右邊,再將兩者相加,而方法B的運算順序則完全被打亂了(其實不是被打亂,只是和我們腦中想象出來以為的運算順序不符,這也是我們錯誤的點),特別是三目運算的后面,顯得非常復雜,但是從 CS$0$0000.HasValue ? CS$0$0000.GetValueOrDefault() : ……………………可以看出,如果a有值的話,就直接把a返回出去了,而不進行后續的運算。

     再思考,為什么會出現這樣的差異,很明顯,只有運算符的優先級才會影響運算的順序,查詢MSDN(http://msdn.microsoft.com/zh-cn/library/6a71f45d(v=vs.100).aspx)得知:加減運算(+、-)比條件運算、null合並運算(?:、??)都高得多。

 

答案:

res1=3;
res2=2;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM