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();
}
對比可以知道,+=運算符果然在返回結果之前系統進行了強制類型轉換。