程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Emit學習-答疑篇-值類型和引用類型在使用時的區別

Emit學習-答疑篇-值類型和引用類型在使用時的區別

編輯:關於.NET

今天下午興沖沖的寫完一段IL代碼,用Reflector轉成C#代碼看了下,沒有問 題,於是引用持久化到硬盤上的動態程序集,想要試一下其中的方法,但是運行 後卻出現了System.AccessViolationException,提示信息為:“嘗試讀取或寫入 受保護的內存。這通常指示其他內存已損壞。”。看著錯誤提示一陣頭大,新配 的電腦內存損壞是不太可能了,只好從自己的程序中找原因。

經過一陣調試,終於找到了引發異常的地方,是在構造函數中用 DateTime.Now.Millisecond初始化隨機數的時候出錯了。看了半天,沒有找到為 什麼出錯,只好祭出強大的Reflector,然後動手寫了相應的C#代碼:

private Random rand = new Random(DateTime.Now.Millisecond);

用Reflector查看系統生成的IL代碼,發現是如下的語句:

.method public hidebysig specialname rtspecialname instance void 

.ctor() cil managed


{


    .maxstack 3


    .locals init (


        [0] valuetype [mscorlib]System.DateTime CS$0$0000)


    L_0000: ldarg.0 


    L_0001: call valuetype [mscorlib]System.DateTime [mscorlib]

System.DateTime::get_Now()


    L_0006: stloc.0 


    L_0007: ldloca.s CS$0$0000


    L_0009: call instance int32 [mscorlib]

System.DateTime::get_Millisecond()


    L_000e: newobj instance void [mscorlib]System.Random::.ctor

(int32)


    L_0013: stfld class [mscorlib]System.Random 

EmitExamples.Animal::rand


    L_0018: ldarg.0 


    L_0019: call instance void [mscorlib]System.Object::.ctor()


    L_001e: nop 


    L_001f: ret 


}

其中我和它的區別就是少加了用紅色標出的兩句IL代碼。搗鼓了近一下午,只 是大致的明白這是因為值類型和引用類型的區別造成的,也記住了在加載引用類 型時,需要使用ldloca指令,自己再用此方法寫了幾個例子,都沒有出問題。但 是只是知其然而不知其所以然,在園子裡找了半天,也沒有發現有相關的文章, 只好作罷,希望有知道的兄弟能夠在回復中給在下指出,我將萬分感激!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved