反射讓程式在執行時檢查、操作型別中繼資料,實現動態建構物件、呼叫方法、載入外部組件等進階功能。本文系統整理 .NET 反射核心概念與實戰技巧。
| 關鍵字 | 用途 | 範例 |
|---|---|---|
is | 型別相容性檢查 | if (obj is MyClass) |
as | 安全轉型,失敗回傳 null | var mc = obj as MyClass; |
typeof | 取得編譯期型別的 Type 物件 | Type t = typeof(StringBuilder); |
MemberInfo,封裝型別完整中繼資料。FullName、IsClass、IsInterface、IsSealed、BaseType、Assembly。GetMethods()、GetProperties()、GetConstructors()、GetFields()、GetEvents()、GetInterfaces()、GetCustomAttributes()。Type t = typeof(MyClass);
MethodInfo[] methods = t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (var m in methods)
{
Console.Write($"{m.ReturnType.Name} {m.Name}(");
var pars = m.GetParameters();
for (int i = 0; i < pars.Length; i++)
Console.Write($"{pars[i].ParameterType.Name} {pars[i].Name}{(i+1<pars.Length?", ":"")}");
Console.WriteLine(")");
}
var obj = new MyClass(10, 20);
MethodInfo mi = t.GetMethod("Set", new[]{typeof(int), typeof(int)});
mi.Invoke(obj, new object[]{9, 10}); // 呼叫 Set(9,10)
ConstructorInfo ci = t.GetConstructor(new[]{typeof(int), typeof(int)});
var instance = ci.Invoke(new object[]{5, 6}); // new MyClass(5,6)
Assembly asm = Assembly.LoadFrom(@"C:\Path\MyLib.dll");
Type[] types = asm.GetTypes();
foreach (Type type in types)
{
Console.WriteLine(type.FullName);
// 進一步用上述技術操作型別
}
Public / NonPublicInstance / StaticDeclaredOnly(不含繼承成員)Expression Tree 編譯委派、DynamicMethod 或 Roslyn 原始碼生成。GetMethods() 等重型 API。