//裝箱拆箱 string name = "Zery"; int age = 22; Console.WriteLine(age.ToString() + name);//已ToString的操作 Console.WriteLine(age+name);//未ToString操作 老規矩,一段C#, ...
//裝箱拆箱 string name = "Zery"; int age = 22; Console.WriteLine(age.ToString() + name);//已ToString的操作 Console.WriteLine(age+name);//未ToString操作
老規矩,一段C#,一段IL
// Method begins at RVA 0x2050 // Code size 48 (0x30) .maxstack 2 .entrypoint .locals init ( [0] string name, [1] int32 age ) IL_0000: nop IL_0001: ldstr "Zery" IL_0006: stloc.0 IL_0007: ldc.i4.s 22 IL_0009: stloc.1 IL_000a: ldloca.s age IL_000c: call instance string [mscorlib]System.Int32::ToString() IL_0011: ldloc.0 IL_0012: call string [mscorlib]System.String::Concat(string, string) IL_0017: call void [mscorlib]System.Console::WriteLine(string) IL_001c: nop IL_001d: ldloc.1 IL_001e: box [mscorlib]System.Int32 IL_0023: ldloc.0 IL_0024: call string [mscorlib]System.String::Concat(object, object) IL_0029: call void [mscorlib]System.Console::WriteLine(string) IL_002e: nop IL_002f: ret
第一段:
IL_0000: nop以上的之前有過介紹,這次不做介紹
ldstr:推送對元數據中存儲的字元串的新對象引用。
stloc.0載入到索引變數的第一位
ldc.i4.s:將位於特定索引處的局部變數的地址載入到計算堆棧上(短格式)。
stloc.1載入到索引變數的第二位
賦值之前一篇也講過,這裡不詳細
IL_000a: ldloca.s age
IL_000c: call instance string [mscorlib]System.Int32::ToString()
IL_0011: ldloc.0
第二段:
ldloca.s :將位於特定索引處的局部變數的地址載入到計算堆棧上。
意思是將string類型的age變數,壓入計算棧中
然後調用函數ToString,並將結果壓入棧中
ldloc.0:將索引 0 處的局部變數載入到計算堆棧上。這樣棧上就有兩個了
IL_0012: call string [mscorlib]System.String::Concat(string, string)
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
第三段:
棧彈出兩個量,然後執行Concat,返回的值壓入棧,
再彈出一個量,在執行WriteLine。
IL_001c: nop
IL_001d: ldloc.1
IL_001e: box [mscorlib]System.Int32
IL_0023: ldloc.0
第四段:
Box:將值類轉換為對象引用(O 類型)。
裝箱box,先將第二個變數值壓入計算棧,然後執行box裝箱(填出棧,做box操作,返回值壓入棧),再壓入第一個變數的值
IL_0024: call string [mscorlib]System.String::Concat(object, object)
IL_0029: call void [mscorlib]System.Console::WriteLine(string)
IL_002e: nop
IL_002f: ret
第五段:
棧中彈出兩個量執行Concat函數,返回值壓入棧
棧中彈出一個量執行WriteLine
因緣際會的相遇,自當有非同尋常的結局 QQ交流群:110826636