天天看點

.Net中的數字類型四則運算的有趣問題

看看下面的代碼:

     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還是基于其它因素的考慮?

繼續閱讀