1. 程式人生 > >《[C#] int與System.Int32有什麽區別》

《[C#] int與System.Int32有什麽區別》

int ima return 基礎 ini nop clas cal black

最近園裏的TeamOne寫了一篇《[C#] int與System.Int32有什麽區別》,發現裏面有不少精彩的評論,所以忍不住想這篇文章總結一下:>

本文的主要參考資料:

1.《理解C#中的System.Int32和int:並非雞和雞蛋》@Author:Dixin

2.《[C#] int與System.Int32有什麽區別》@Author:TeamOne

一.問題的來源

MSDN說,int只不過是System.Int32的別名而已,也就是說:

int i=1;
System.Int32 i=1;

應該是等價的,或者說毫無區別的。

但在Dixin在用Reflector對.Net Framework的mscorlib.dll進行反匯編時,發現事情好像並不是這樣,看下圖:

技術分享圖片

上圖是Dixin通過Reflector對mscorlib.dll進行反匯編後看到的System.Int32的定義,在上圖中,我們看到Int32的定義中用到了int,如果按MSDN中說,int只是System.Int32的別名,那問題就來了:

(1).使用int和使用System.Int32是沒有區別的。

(2).在C#的Struct定義中,字段中存在類型為自己的變量,是不允許的,例子如下:

public struct Test
{
    public Test value;
}

上面這個例子編譯會失敗。由於System.Int32等價於int ,所以System.Int32的編譯也應該會失敗的!但事實上是,Reflector反編譯出來的代碼的確顯示System.Int32定義中使用了int。這就不禁讓人懷疑,int和System.Int32的關系到底是不是如MSDN所說的這麽簡單呢??究竟int是System.Int32的別名呢?還是System.Int32對int進行了封裝呢?

二.int和System.Int32的關系

下圖是我從微軟官方介紹裏截取的,我們先簡單看一下.Net Framework的架構:

技術分享圖片

.Net Framework是一個基礎平臺,它要支持建立在此基礎上的各種語言,以及跨語言程序之間的通信。如圖:

技術分享圖片

由於上述原因,.Net Framework對外提供的資源必須是通用的,並且避免使用某種語言的特有稱呼,以免造成不必要的混淆。

於是,這就有了int和System.Int32,它們的關系如下圖:

技術分享圖片

System.Int32是.Net Framework對32位整數的標識,MSDN對這種類型標示的稱呼是User Type。而int

則是c#語言裏面的特有稱呼(這裏它對應的.Net Framework裏的System.Int32),MSDN對c#的int的稱呼是Keyword。int就是System.Int32的別名而已!

那為什麽我們在用Reflector反編譯mscorlib.dll的時候,會得出第一幅圖那種結果呢?

是這樣的,在.Net Framework運行庫裏,有一種最基礎的數據類型,叫“基元類型(primitive)”。這種數據類型是只提供給.Net Framework內部使用,外面是看不見的。其實在真正微軟的System.Int32的源碼中,用到的應該是int32。但是由於int32不是c#提供的類型,所以Reflector會自動把int32逆向為c#的int,這也就是為什麽我們會在System.Int32定義中看到int的存在了。

這裏我引用Dixin文章裏的一段IL代碼證明int32的存在:>

C#代碼:

public int TestMethod(int value)
{
    return value * 2;
}

對應得IL代碼:

.method public hidebysig instance int32 TestMethod(int32 ‘value‘) cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 CS$1$0000)
    L_0000: nop 
    L_0001: ldarg.1 
    L_0002: ldc.i4.2 
    L_0003: mul 
    L_0004: stloc.0 
    L_0005: br.s L_0007
    L_0007: ldloc.0 
    L_0008: ret 
}

想了解更多的關於“基元類型”的資料,可以參考這篇文章《認識基元類型、FCL類型及與CLR的相容情況》。

三.System.Int32在64位機器上

System.Int32在64位機器上還是表示32位的整數,也就是說C#的int在64位機器上也還是表示32位的整數。至於為什麽,看下圖:

技術分享圖片

如果System.Int32在64位機器為64bit,那麽,這將會使在32位機器上的C#程序難以和64位上的C#程序溝通,試想一下,要把64bit的數據塞進32bit的空間中是一件多惡心的事情啊!所以,System.Int32在64位機器還是表示32位的長度,是很合理的。

《[C#] int與System.Int32有什麽區別》