首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Emit ILGenerator 實戰:動態產生方法體與 Mock 介面示範

     編輯:關於.NET

接續《Emit 基本操作》,本文聚焦 ILGenerator 將 IL 指令注入方法體,並完成簡易 Mock 介面動態實作。

CIL 指令速覽

.NET 編譯器產生 IL (操作碼/Opcode) 與 CIL 指令 (Directive,如 .assembly, .class, .method)。方法體含 .maxstack、標籤 (Label) 與操作碼 (如 ldstr, call, ret)。計算堆疊遵循「用前壓入、用後彈出」原則,編譯器會優化 .maxstack 大小。

HelloWorld IL 逐行解析

.entrypoint
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Hello World"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret

ldstr 壓入字串參考,call 自動彈出堆疊頂作參數呼叫,ret 返回。

裝箱/拆箱 IL 範例

.locals init ([0] int32 v1, [1] object v2)
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: box [mscorlib]System.Int32
IL_0009: stloc.1
IL_000a: ldloc.1
IL_000b: unbox.any [mscorlib]System.Int32
IL_0010: call void [mscorlib]System.Console::WriteLine(int32)

三種取得 ILGenerator 途徑

  • ConstructorBuilder.GetILGenerator()
  • DynamicMethod.GetILGenerator() (無需預建組件/模組/型別)
  • MethodBuilder.GetILGenerator()

簡易 Mock 實作

目標:Mock<IAssessmentAopAdviceProvider> mocker = new Mock<...>(); mocker.Setup(t=>t.Before(3)).Returns("HelloWorld!"); Console.WriteLine(mocker.Obj.Before(2));

核心工廠 AdviceProviderFactory 動態建立型別實作介面:

MethodBuilder mb = typeBuilder.DefineMethod("Before", MethodAttributes.Public|Virtual, typeof(string), new[]{typeof(int)});
ILGenerator gen = mb.GetILGenerator();
LocalBuilder loc = gen.DeclareLocal(typeof(string));
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Ldstr, returnValue); // "HelloWorld!"
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ret);
Type t = typeBuilder.CreateType();
assemblyBuilder.Save("test.dll");
return Activator.CreateInstance(t) as IAssessmentAopAdviceProvider;

反組譯驗證產生 IL 符合預期,主控台測試輸出 "HelloWorld!" 成功。

作者:玄魂
出處:https://www.cnblogs.com/xuanhun/

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved