using System;
using System.Reflection;
using System.Reflection.Emit;
public class TestReflection {
private string file = @"TestReflection.exe";
static void Main(string[] args) {
TestReflection test = new TestReflection();
test.DisplayModules();
test.DisplayTypes();
test.DisplayMethods();
test.InvokeStaticMethod();
test.InvokeMethod();
}
// 顯示所有模組
public void DisplayModules() {
Console.WriteLine("display modules ...");
Assembly assembly = Assembly.LoadFrom(file);
foreach (Module module in assembly.GetModules())
Console.WriteLine("module name: " + module.Name);
}
// 顯示所有型別
public void DisplayTypes() {
Console.WriteLine("display types ...");
Assembly assembly = Assembly.LoadFrom(file);
foreach (Type type in assembly.GetTypes())
Console.WriteLine("type name: " + type.FullName);
}
// 顯示指定型別所有方法
public void DisplayMethods() {
Console.WriteLine("display methods in TestReflection Type ...");
Assembly assembly = Assembly.LoadFrom(file);
Type type = assembly.GetType("TestReflection");
foreach (MethodInfo method in type.GetMethods())
Console.WriteLine("method name: " + method.Name);
}
// 調用靜態方法
public void InvokeStaticMethod() {
Console.WriteLine("Invoke static method ...");
Assembly assembly = Assembly.LoadFrom(file);
Type type = assembly.GetType("TestSubClass");
type.InvokeMember("SayHello", BindingFlags.InvokeMethod, null, null, new object[] { });
}
// 調用實例方法
public void InvokeMethod() {
Console.WriteLine("Invoke Method ...");
Assembly assembly = Assembly.LoadFrom(file);
Type type = assembly.GetType("TestSubClass");
object obj = Activator.CreateInstance(type);
TestClass tc = (TestClass)obj;
type.InvokeMember("Test1", BindingFlags.InvokeMethod, null, tc, new object[] { });
type.InvokeMember("Test2", BindingFlags.InvokeMethod, null, tc, new object[] { });
}
}
public interface TestClass {
void Test1();
void Test2();
}
public class TestSubClass : TestClass {
public void Test1() { Console.WriteLine("This is TestSubClass.Test1"); }
public void Test2() { Console.WriteLine("This is TestSubClass.Test2"); }
public static void SayHello() { Console.WriteLine("This is TestSubClass.SayHello"); }
}
display modules ...
module name: TestReflection.exe
display types ...
type name: TestReflection
type name: TestClass
type name: TestSubClass
display methods in TestReflection Type ...
method name: GetHashCode
method name: Equals
method name: ToString
method name: DisplayModules
method name: DisplayTypes
method name: DisplayMethods
method name: InvokeStaticMethod
method name: InvokeMethod
method name: Test2
method name: GetType
Invoke static method ...
This is TestSubClass.SayHello
Invoke Method ...
This is TestSubClass.Test1
This is TestSubClass.Test2
| 方法 | 用途 |
|---|---|
Assembly.LoadFrom(path) | 從路徑載入,支援相對路徑,載入上下文為 LoadFrom |
Assembly.Load(name) | 從 GAC 或探索路徑載入,載入上下文為 Load |
Assembly.ReflectionOnlyLoadFrom(path) | 僅檢視中繼資料,不可執行程式碼 |
包含繼承自 Object 的方法(GetHashCode、Equals、ToString、GetType),順序不保證,勿依賴順序邏輯。
// 靜態方法
type.InvokeMember("SayHello", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, args);
// 實例方法
type.InvokeMember("Test1", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, instance, args);
// 非公開成員
BindingFlags.NonPublic | BindingFlags.Instance
// 忽略大小寫
BindingFlags.IgnoreCase
// 無參數建構子
object obj = Activator.CreateInstance(type);
// 有參數建構子
object obj = Activator.CreateInstance(type, arg1, arg2);
// 指定建構子綁定旗標
object obj = Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Instance, null, args, null);
| 技術 | 相對效能 | 適用場景 |
|---|---|---|
| 直接呼叫 | 1x (基準) | 已知型別、高頻呼叫 |
| 委派快取 | ~1.5x | 重複調用同一方法 |
| MethodInfo.Invoke | ~50-100x | 動態型別、低頻 |
| 動態方法 | ~2-5x | 高頻動態調用、IL 生成 |
| 表達式樹編譯 | ~5-10x | Lambda 編譯、LINQ Provider |
private static readonly Dictionary> _methodCache = new();
public object InvokeCached(object target, string methodName, params object[] args) {
var key = $"{target.GetType().FullName}.{methodName}";
if (!_methodCache.TryGetValue(key, out var func)) {
var method = target.GetType().GetMethod(methodName);
func = (instance, parameters) => method.Invoke(instance, parameters);
_methodCache[key] = func;
}
return func(target, args);
}
ReflectionPermission(全信任環境預設滿足)ReflectionPermissionFlag.MemberAccessSystem.Reflection.Metadata反射是 C# 動態能力的核心,支援外掛、框架、工具開發。關鍵在於平衡靈活性與效能:熱路徑使用委派快取或原始碼生成,冷路徑直用 MethodInfo.Invoke。掌握 BindingFlags 組合、建構子選擇、泛型方法構造(MakeGenericMethod)是進階反射必備技能。