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

C# 反射實戰:動態載入 DLL、建立實例、呼叫靜態/實例方法

     編輯:關於C#

反射允許執行期檢查中繼資料、動態載入組件、建立型別實例並呼叫成員。本文示範完整流程:編譯類別庫 DLL、主程式 Assembly.LoadFile、GetType、CreateInstance、GetMethod、Invoke 呼叫無參/有參/靜態/實例方法。

步驟 1:建立類別庫專案

新增 Class Library 專案 Webtest,加入類別 ReflectTest:


namespace Webtest
{
    public class ReflectTest
    {
        public ReflectTest() { }
        public string WriteString(string s) => "歡迎您," + s;
        public static string WriteName(string s) => "歡迎您光臨," + s;
        public string WriteNoPara() => "您使用的是無參數方法";
    }
}

編譯產出 TestReflect.dll。

步驟 2:主程式反射呼叫


using System.Reflection;

public void TestReflection()
{
    try
    {
        // 1. 載入組件
        Assembly asm = Assembly.LoadFile(@"D:\TestReflect.dll");

        // 2. 取得型別(需完整命名空間.類別名)
        Type type = asm.GetType("Webtest.ReflectTest");

        // 3. 建立實例(實例方法需實例)
        object obj = asm.CreateInstance("Webtest.ReflectTest");

        // 4. 取得方法並呼叫
        // 實例方法
        MethodInfo mi = type.GetMethod("WriteString");
        string result = (string)mi.Invoke(obj, new object[] { "江立俊" });
        Console.WriteLine(result); // 歡迎您,江立俊

        // 靜態方法:第一參數傳 null
        mi = type.GetMethod("WriteName");
        result = (string)mi.Invoke(null, new object[] { "江立俊" });
        Console.WriteLine(result); // 歡迎您光臨,江立俊

        // 無參實例方法
        mi = type.GetMethod("WriteNoPara");
        result = (string)mi.Invoke(obj, null);
        Console.WriteLine(result); // 您使用的是無參數方法
    }
    catch (Exception ex)
    {
        Console.WriteLine("反射錯誤:" + ex.Message);
        // 實務上記錄 ex.ToString() 含堆疊追蹤
    }
}

關鍵 API 對照

需求API備註
載入檔案組件Assembly.LoadFile(path)需完整路徑,不驗證證據;LoadFrom 會進入 LoadFrom 上下文
依名稱取得型別asm.GetType("Ns.Class")大小寫敏感,找不到回傳 null
建立實例asm.CreateInstance("Ns.Class") / Activator.CreateInstance(type)呼叫無參建構子;有參用 Activator.CreateInstance(type, args)
取得方法type.GetMethod("Name") / GetMethods()多載需用 GetMethod("Name", types[])
呼叫方法mi.Invoke(obj, args[])靜態方法 obj 傳 null;傳回值需轉型
取得屬性/欄位type.GetProperty/Field → GetValue/SetValue

進階主題

  • 泛型方法:mi.MakeGenericMethod(typeArgs[]).Invoke(...)。
  • 非公用成員:BindingFlags.NonPublic | BindingFlags.Instance。
  • 效能優化:反射較慢,熱路徑請快取 MethodInfo、PropertyInfo,或用 Delegate.CreateDelegate、Expression 樹、FastMember 套件。
  • 依賴注入容器:Autofac、Microsoft.Extensions.DI 內部大量使用反射掃描、建構、注入。
  • AssemblyLoadContext:.NET Core 3.0+ 支援組件隔離載入/卸載,解決插件系統版本衝突。

應用場景

  • 插件/模組動態載入。
  • 序列化/反序列化、ORM 映射。
  • 單元測試框架自動發現測試方法。
  • 設定檔驅動的物件建構工廠。

反射是 .NET 動態能力的基石,善用它能構建極具延展性的架構,但請謹記「快取中繼資料、避免熱路徑反射」的效能鐵律。

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