2012-10-26 23 views
7

如果引擎蓋下得到的,在C#中值類型由編譯器/ CLR處理非常特別。但CLR內部的類型更加特殊。這裏是我的意思是:是否有可能在C#中創建System.Int32?

int a = 5; 
int b = 10; 
int с = a + b; 
a.CompareTo(b); 

你可以用你的鼠標int在Visual Studio中徘徊,看到實際上它是System.Int32結構。沒關係。現在,你可以抓住ILDASM和考慮什麼System.Int32是:翻開它與int32類型的一個領域是非常簡單的結構(這是int32內部CLR)並沒有重載運營商的補充。

那麼,如何int с = a + b的作品呢?我再一次抓住ILDasm並觀察IL。原來,有在IL代碼中沒有System.Int32:編譯器自動理解,它應該與int32替換它。 IL指令add適用於棧上的int32。 CLR允許我在int32上調用System.Int32的實例方法。對我來說看起來像是一些黑魔法。

所以,在這裏不用純理論性的問題:似乎System.Int32的類型是像任何其他的,可以在C#中創建不知何故?如果可以,你可以做任何有用的事情(實際int32字段是私人的)?

編輯:好吧,讓它多一點明確:這個問題有什麼關於int是別名System.Int32。可以舉一個例子,將int替換爲System.Int32,並跳過示例後的第一段。真正的問題是有可能在您的IL代碼中有valuetype [mscorlib]System.Int32 a而不僅僅是int32 a

+1

'int a = new int();'與System.Int32 a = new System.Int32();'相同。這只是語法糖。兩者都將在內部表示爲'int32'。儘管在CLR中有一些「神奇」處理的結構,但它比其他一些Java語言更好,在這些語言中,獲得所有額外功能需要裝箱/拆箱。 –

回答

2

所以,考慮下面的代碼:

static void Main(string[] args) 
    { 
     int x = 5; 
     Print(x); 
     Console.ReadLine(); 
    } 

    static void Print(object x) 
    { 
     int y = (int)x; 
     Console.WriteLine(y); 
    } 
在ILDASM

.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    .maxstack 1 
    .locals init ([0] int32 x) 
    IL_0000: nop 
    IL_0001: ldc.i4.5 
    IL_0002: stloc.0 
    IL_0003: ldloc.0 
    IL_0004: box  [mscorlib]System.Int32 
    IL_0009: call  void Test.Program::Print(object) 
    IL_000e: nop 
    IL_000f: call  string [mscorlib]System.Console::ReadLine() 
    IL_0014: pop 
    IL_0015: ret 
} // end of method Program::Main 

.method private hidebysig static void Print(object x) cil managed 
{ 
    .maxstack 1 
    .locals init ([0] int32 y) 
    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: unbox.any [mscorlib]System.Int32 
    IL_0007: stloc.0 
    IL_0008: ldloc.0 
    IL_0009: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_000e: nop 
    IL_000f: ret 
} // end of method Program::Print 

[mscorlib]System.Int32僅用於裝箱/拆箱。當變量處於堆棧狀態時,始終爲int32


Int32 and int

它可能會以爲System.Int32的一個陰影類型INT32很有幫助。

下面的C#代碼:

int x = 0; 
x.ToString(); 

這是在IL:

ldc.i4.0 
stloc.0 
ldloca.s 0 
call instance class System.String [mscorlib]System.Int32::ToString() 
pop 

注意它是如何通過一個Int32成一個看似不相容System.Int32 結構。該引擎允許這個原因,它已被硬連線識別 System.Int32作爲int32的陰影類型。

+0

可以進一步移動拳擊的例子: 'int a = 5; int b = 10; 對象oa = a; Object ob = b; Int32с=((Int32)oa)+((Int32)ob);' 如果您檢查IL,您會看到: 'IL_0013:ldloc。2 IL_0014:unbox.any [mscorlib程序] System.Int32 IL_0019:ldloc.3 IL_001a:unbox.any [mscorlib程序] System.Int32 IL_001f:add' 所以,作爲'add'可與CLR原語一個可以得出的結論是,「沒有裝箱的System.Int32」和「System.Int32」僅用於創建類型對象。 –

0

的CLR具有一組它們由CorElementType枚舉定義的原始類型。 http://msdn.microsoft.com/en-us/library/ms232600.aspx

add,sub,div,rem等操作碼對這些類型進行操作。 JIT將把這些變成一些快速彙編代碼。你不能定義新的。如果你感興趣,你可以看看它使用SOS生成的代碼。

如果要模擬語言​​體驗,可以在類型中使用運算符重載。 http://msdn.microsoft.com/en-us/library/8edha89s.aspx

1

int32 VS int(== System.Int32

Understanding .NET Primitive Types來自:

INT32是原始一個CLR。然後在FCL中,它由 System.Int32結構體表示。 System.Int32的整數值在 的m_value字段中保留,並且在 System.Int32上定義了許多與整數有關的方法。

在C#中,int只是System.Int32的別名,由C# 編譯器支持。所以int和System之間沒有依賴關係。INT32

IL "The Language of CLR"

下.NET所有編譯會生成中間語言無論 什麼語言來開發應用程序。實際上,CLR不會知道用於開發應用程序的語言。所有語言 編譯器將生成統一的通用語言,稱爲Intermediate 語言。

所以,在C#System.Int32是我們的IL int32。我不知道從C#代碼直接與IL一起工作的方式,實際上沒有看到任何理由。

有一個:Tool to allow inline IL in C#/VB.Net


至於int VS System.Int32

上int和System.Int32一個交上SO:C#, int or Int32? Should I care?

在MSDN:

  1. Int32 Structure
  2. int (C# Reference)

這都是一樣的:

Int32 i = new Int32(); 
Int32 j = 5; 
int x1 = 2; 
Int32 x2 = x1; 

int是這麼說語法糖 ...實際上它是System.Int32

除了看看C#語言規格4.1.4簡單類型:

C#提供了一組名爲簡單類型的預定義結構類型。 的簡單類型通過保留字標識,但這些 保留字僅僅是用於預定義結構類型在 系統的命名空間的別名,如在表

其中

  1. 短=>系統描述.Int16
  2. INT => System.Int32
  3. 長=> System.Int64

等。

+0

但'int32'和'Int32'不一樣。在C#中沒有'int32'這樣的東西。 –

+0

閱讀此:http://weblogs.asp.net/dixin/archive/2007/12/20/understanding-net-primitive-types.aspx – horgh

+0

好文章。但它明確指出我上面寫道:「Int32'和'int32'不一樣(也是'int'!='int32')。我不是在這裏爭論'Int32'和'int'。問題是關於'Int32'和'int32'。 –

相關問題