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

Emit 入門第一課:DynamicMethod 實現 Hello World

     編輯:關於.NET

System.Reflection.Emit 最輕量的切入點是 DynamicMethod——無需創建程序集/模塊/類型,直接在內存生成靜態方法並通過委托執行。本文以經典「Hello World」演示核心 API:DynamicMethod、ILGenerator、OpCodes、CreateDelegate。

完整代碼

using System;
using System.Reflection.Emit;

namespace EmitExamples.HelloWorld
{
    class Program
    {
        private delegate void HelloWorldDelegate();

        static void Main()
        {
            // 1. 定義動態方法:無返回值、無參數
            var helloMethod = new DynamicMethod("HelloWorld", null, null);

            // 2. 獲取 IL 生成器
            var il = helloMethod.GetILGenerator();

            // 3. 發射指令
            il.Emit(OpCodes.Ldstr, "Hello World!");                    // 壓入字符串
            il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new[] { typeof(string) })); // 調用 Console.WriteLine
            il.Emit(OpCodes.Ret);                                      // 返回

            // 4. 創建委托並執行
            var hello = (HelloWorldDelegate)helloMethod.CreateDelegate(typeof(HelloWorldDelegate));
            hello(); // 輸出: Hello World!
        }
    }
}

關鍵步驟解析

  1. DynamicMethod 構造函數:(name, returnType, parameterTypes, ownerModule/ownerType)。傳 null 表示無參無返回,最後參數可指定關聯模塊以訪問 internal 成員。
  2. ILGenerator.Emit:核心發射方法,接受 OpCode 及可選操作數。Ldstr 專用於字符串字面量。
  3. 方法調用:OpCodes.Call 調用靜態方法 Console.WriteLine(string),需通過反射獲取 MethodInfo。
  4. CreateDelegate:將動態方法綁定到強類型委托,實現零反射調用開銷。

進階變體:帶參數與返回值

var addMethod = new DynamicMethod("Add", typeof(int), new[] { typeof(int), typeof(int) });
var il = addMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Ret);

var add = (Func<int, int, int>)addMethod.CreateDelegate(typeof(Func<int, int, int>));
Console.WriteLine(add(3, 5)); // 8

DynamicMethod vs 完整 AssemblyBuilder

特性DynamicMethodAssemblyBuilder
持久化❌ 僅內存✅ 可保存 .dll
類型定義❌ 僅方法✅ 完整類型系統
訪問非公有成員✅ 關聯模塊可訪問 internal✅ 同程序集可訪問
適用場景輕量級動態委托、表達式樹編譯動態代理、ORM、編譯器後端

調試技巧

  • 生成後用 ildasm /text DynamicMethod.dll 查看 IL (需先保存為模塊)。
  • Visual Studio 「模塊」視窗可載入動態模塊斷點調試 (需 DebuggableAttribute)。
  • 發射錯誤會在 CreateDelegate 或調用時拋 VerificationException,善用 peverify。

掌握 DynamicMethod,你就擁有了運行時生成高性能委托的鑰匙,這是表達式樹、動態代理、序列化庫的核心基石。

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