今天下午興沖沖的寫完一段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指令,自己再用此方法寫了幾個例子,都沒有出問題。但 是只是知其然而不知其所以然,在園子裡找了半天,也沒有發現有相關的文章, 只好作罷,希望有知道的兄弟能夠在回復中給在下指出,我將萬分感激!