看看下面的代碼:
sbyte sba, sbb,sbv;
sba = 1;
sbb = 2;
sbv = sba + sbb;
byte ba, bb, bv;
ba = 1;
bb = 2;
bv = ba + bb;
short sa, sb, sv;
sa = 1;
sb = 2;
sv = sa + sb;
ushort usa, usb, usv;
usa = 1;
usb = 2;
usv = usa + usb;
MessageBox.Show(string.Format("{0},{1},{2},{3}", sbv, bv, sv, usv));
你覺得這段代碼能否正确執行?結果會怎樣?
用VS2005打開項目測試一下你就會發現,這段代碼會出現編譯錯誤.
正确的代碼應該如下:
sbyte sba, sbb,sbv;
sbv = (sbyte)(sba + sbb);
bv = (byte)(ba + bb);
sv = (short)(sa + sb);
usv = (ushort)(usa + usb);
這是什麼原因呢?
其實CLR底層隻支援 int,int64,native int, float , double幾種資料類型.
像上面的sbyte,byte,short,ushort, clr底層是不支援的,在底層這些類型是用int表示的.
CLR的堆棧中壓入的數字,最小是4位元組,小于4位元組的會根據其類型進行符号擴充或者0擴充為4位元組int型.
這樣四則運算的結果也是int型,最後再指派需要進行強制類型轉換.
分析一下編譯後的IL代碼就清楚了.
下面這個代碼為什麼能編譯呢?
short sb;
sb=2;
sb += 1;
其實編譯後的IL代碼中最後指派也包含了類型轉換操作.
應該是編譯器自動識别,然後自動添加的類型轉換操作.
但是像上面的代碼也編譯出錯,這個也能進行類型推斷,自動添加資料類型轉換啊.
不知道微軟這麼設計是bug還是基于其它因素的考慮?