反射讓 C# 程式在執行期發現型別資訊、動態建立物件、呼叫方法。本文完整示範:建立類別庫 DLL → 主程式反射載入 → 呼叫實例方法、靜態方法、無參數方法,並處理例外與資源釋放。
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 放置於 D:\。
public void TestReflection()
{
Assembly ass = null;
Type type = null;
object obj = null;
try
{
// 1. 載入組件 (絕對路徑)
ass = Assembly.LoadFile(@"D:\TestReflect.dll");
// 2. 取得型別 (必須含命名空間)
type = ass.GetType("Webtest.ReflectTest");
// 3. 建立實例 (實例方法需物件)
obj = ass.CreateInstance("Webtest.ReflectTest");
// 4. 取得並呼叫實例方法
var method = type.GetMethod("WriteString");
string result = (string)method.Invoke(obj, new object[] { "jianglijun" });
Console.WriteLine(result); // 歡迎您,jianglijun
// 5. 取得並呼叫靜態方法 (第一參數傳 null)
method = type.GetMethod("WriteName");
result = (string)method.Invoke(null, new object[] { "jianglijun" });
Console.WriteLine(result); // 歡迎您光臨,jianglijun
// 6. 取得並呼叫無參數實例方法
method = type.GetMethod("WriteNoPara");
result = (string)method.Invoke(obj, null);
Console.WriteLine(result); // 您使用的是無參數方法
}
catch (Exception ex)
{
Console.WriteLine("反射錯誤: " + ex.Message);
}
finally
{
// 釋放參考 (組件無法卸載,僅清除變數)
ass = null; type = null; obj = null;
}
}
| 操作 | API | 關鍵參數 |
|---|---|---|
| 載入組件 | Assembly.LoadFile(path) | 絕對路徑,不鎖定檔案 |
| 載入組件 | Assembly.LoadFrom(path) | 相對路徑,會鎖定檔案 |
| 取得型別 | ass.GetType("Full.Name") | 命名空間+類別名,區分大小寫 |
| 建立實例 | ass.CreateInstance("Full.Name") | 呼叫無參建構函數 |
| 取得方法 | type.GetMethod("Name") | 可加 BindingFlags 過載搜尋私有/靜態 |
| 呼叫方法 | method.Invoke(obj, args[]) | 靜態方法 obj 傳 null;陣列參數對應簽名 |
GetMethod 無參數版本回傳第一個匹配,建議使用 GetMethod("Name", new Type[] { typeof(string) }) 精確匹配簽名。BindingFlags.NonPublic | BindingFlags.Instance。Invoke 第二參數為 object[],單一參數也要包在陣列 new object[] { val };無參傳 null 或 new object[0]。Invoke 拋出 TargetInvocationException,真實例外在 InnerException。AssemblyLoadContext (.NET Core 3.0+) 實現插件熱重載。反射是 C# 動態性的基石,支援插件架構、序列化、ORM、測試框架等核心基礎設施。掌握 Assembly.LoadFile、GetType、CreateInstance、GetMethod、Invoke 五大核心 API,並理解靜態/實例/無參數方法的呼叫差異,是進階 C# 開發者必備技能。生產代碼中務必加入快取與例外處理,必要時改用委派或原始碼產生提升效能。