s+=1和s=s+1

    s=s+1與s+=1在官方網站上據說是等效的,可是在實際的應用中,它們之間還是有一點小小的區別,這些區別造成了一些困惑,現在就對這些區別做一些解釋。

    前幾天一個很牛的朋友問我:“s=s+1與s+=1有什麼區別?”,我認爲他在開玩笑,因爲以這個朋友的實力,不會不知道這個的,我認爲這是一個陷阱,趕快到MSDN上 進行查詢,得到的結果是:

使用 += 賦值運算符的表達式,

x += y等效於 x = x + y。既然MSDN上都說了“等效”,當然它們應該是一樣的。我的朋友立即給我發過來一段代碼,   short s = 1;         s = s + 1;         short n = 1;         n += 1;         Console.ReadKey();其中s=s+1編譯錯誤:無法將類型“int”隱式轉換爲“short”。存在一個顯式轉換(是否缺少強制轉換?),並且定位在s=s+1這一行,從這裏看兩個還真的不等效。於是將代碼改寫爲short s = 1;            s = (short)(s + 1);            short n = 1;            n += 1;            Console.ReadKey();編譯通過,於是推測s=s+1這個表達式中,1被默認的看爲整型int,根據運算規則,s+1中的s也會隱式的轉換成int,於是結果就變成了int類型,由於int類型比short類型的精度高,所以將int賦值給short時,需要進行強制類型轉換,於是,我又編寫了下面的代碼            short s = 1;

            short k = 2;

            s = s+k;

            short n = 1;

            n += 1;

            Console.ReadKey();

編譯仍然不能通過,提示信息錯誤無法將類型“int”隱式轉換爲“short”。存在一個顯式轉換(是否缺少強制轉換?),暈倒,short+short得出的結果仍然是int類型,爲了測試這個想法,於是編寫代碼如下:

            short s = 1;

            short k = 2;

            Console.WriteLine((s + k).GetType().FullName);

            short n = 1;

            n += 1;

            Console.ReadKey();

得到的結果是System.Int32(在c#中,short對應System.Int16,int對應System.Int32),在C#中,爲數值類型和字符串類型預定義了二元 + 運算符。其實+運算符應該也是一個函數調用,只是這個函數的名字比較特殊罷了。

當一個函數的名稱相同,而要根據參數的類型或者參數的個數的不同而有不同的實現的時候,需要進行函數的重載,問題可能就是出現在這個+運算符的重載了。

推測在系統的內部,系統只重載了 int operator+(int,int)這樣的函數,在進行short+short運算時,系統尋找精確的匹配,但是沒有找到,可是將short升級爲int是一個自動的過程,於是系統調用了int operator(int,int)這個函數,得到的結果也就被轉化爲int類型,就出現了上面的錯誤。

而+=這個運算符與+運算符一樣,但是系統重載了short operator +=(short,short)或者short operator +=(int,int),這個函數的具體實現沒辦法看到,可是據推測應該是這樣

short operator+=(int b)

{

   return (short)(this+b);

}

也就是在返回數據的結果前,系統自己做了強制類型轉換。爲了驗證這個思想,我又做了兩件事情。

第一:對short類型擴展一個方法(vs2008的擴展方法),該方法實現的是兩個short類型的變量的加和,但是在返回結果前,對結果進行強制類型轉換。代碼如下:

namespace ConsoleApplication1

{

    static class Myshort

    {

        public static short add(this short a,short b)

        {

            return (short)(a+b);

        }

    }

}

重新編寫代碼

            short s = 1;

            short k = 2;

            s=s.add(k);

沒有任何問題,編譯通過。

   第二:對源代碼進行反編譯,看看反編譯的代碼

源代碼如下:

static void Main(string[] args)

        {

            short s = 1;

            short k = 2;

            s=s.add(k);

            short n = 1;

            n += 1;

            Console.ReadKey();

        }

生成的反編譯的代碼:

private static void Main(string[] args)

{

    short s = 1;

    short k = 2;

    s = s.add(k);

    short n = 1;

    n = (short) (n + 1);

    Console.ReadKey();

}

對比可以知道,+=運算符果然在返回結果之前系統進行了強制類型轉換。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章