反射是 .NET 執行期型別發現機制的核心。System.Reflection 命名空間提供完整的 API,讓程式能檢視、操作組件、模組、型別與成員中繼資料。本文系統整理核心類別、Type 關鍵方法、取得 Type 實例的三種方式。
| 類別 | 用途 | 關鍵特性 |
|---|---|---|
Assembly |
載入、檢視、操作組件 | GetTypes(), GetManifestResourceStream(), Load()/LoadFrom() |
AssemblyName |
組件身分資訊 | 版本、文化特性、公開金鑰標記、完整名稱 |
Type |
型別中繼資料核心 | GetMethods(), GetProperties(), GetFields(), GetConstructors(), InvokeMember() |
MemberInfo |
所有成員的抽象基類 | Name, DeclaringType, MemberType, GetCustomAttributes() |
MethodInfo |
方法中繼資料 | ReturnType, GetParameters(), Invoke(), IsStatic, IsVirtual |
PropertyInfo |
屬性中繼資料 | PropertyType, GetValue/SetValue, CanRead/CanWrite, GetIndexParameters() |
FieldInfo |
欄位中繼資料 | FieldType, GetValue/SetValue, IsStatic, IsInitOnly, IsLiteral |
EventInfo |
事件中繼資料 | EventHandlerType, AddEventHandler/RemoveEventHandler |
ConstructorInfo |
建構函式中繼資料 | GetParameters(), Invoke(), IsStatic, IsPublic |
ParameterInfo |
參數中繼資料 | ParameterType, Name, Position, DefaultValue, IsOptional |
Module |
多檔組件中的模組 | GetTypes(), Assembly, FullyQualifiedName |
type.IsClass // 是否為類別
type.IsInterface // 是否為介面
type.IsValueType // 是否為實質型別
type.IsAbstract // 是否為抽象
type.IsSealed // 是否為密封
type.IsEnum // 是否為列舉
type.IsArray // 是否為陣列
type.IsGenericType // 是否為泛型
type.IsPrimitive // 是否為基本型別
type.IsPublic // 是否為公開
type.IsNested // 是否為巢狀型別
// 單數:取得特定名稱成員
type.GetMethod("MethodName")
type.GetProperty("PropertyName")
type.GetField("FieldName")
type.GetEvent("EventName")
type.GetConstructor(types)
type.GetMember("MemberName")
// 複數:取得所有符合條件成員
type.GetMethods(bindingFlags)
type.GetProperties(bindingFlags)
type.GetFields(bindingFlags)
type.GetEvents(bindingFlags)
type.GetConstructors(bindingFlags)
type.GetMembers(bindingFlags)
type.GetNestedTypes(bindingFlags)
// 依條件查詢成員
type.FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance,
Type.FilterName, "Get*");
// 靜態方法:依名稱取得 Type
Type.GetType("Namespace.ClassName")
Type.GetType("Namespace.ClassName, AssemblyName") // 跨組件
Type.GetType("Namespace.ClassName", false, true) // 不拋例外、不區分大小寫
// 巢狀型別
Type.GetType("OuterClass+NestedClass")
// 動態調用(晚期繫結)
type.InvokeMember("MethodName", BindingFlags.InvokeMethod, null, instance, args)
| 方式 | 語法 | 特點 | 適用場景 |
|---|---|---|---|
| 物件.GetType() | obj.GetType() |
需先有實例、取得執行期實際型別 | 已有物件、多型情境 |
| Type.GetType() | Type.GetType("FullName") |
無需實例、支援字串動態指定、跨組件 | 設定檔驅動、外掛載入、序列化還原 |
| typeof 運算子 | typeof(MyClass) |
編譯期繫結、型別安全、效能最佳 | 已知型別、泛型參數、屬性標記 |
控制反射搜尋範圍的關鍵旗標(可組合):
BindingFlags.Public // 公開成員
BindingFlags.NonPublic // 非公開成員
BindingFlags.Instance // 實例成員
BindingFlags.Static // 靜態成員
BindingFlags.DeclaredOnly // 僅宣告於此型別(不含繼承)
BindingFlags.FlattenHierarchy // 靜態成員包含繼承鏈
// 常用組合
var flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
public static void DumpTypeInfo(Type type)
{
Console.WriteLine($"=== {type.FullName} ===");
Console.WriteLine($"Base: {type.BaseType?.FullName ?? "null"}");
Console.WriteLine($"Interfaces: {string.Join(", ", type.GetInterfaces().Select(i => i.Name))}");
Console.WriteLine($"IsClass: {type.IsClass}, IsInterface: {type.IsInterface}, IsValueType: {type.IsValueType}");
Console.WriteLine("\n--- Constructors ---");
foreach (var ctor in type.GetConstructors())
Console.WriteLine($" {ctor}");
Console.WriteLine("\n--- Methods ---");
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
Console.WriteLine($" {method.ReturnType.Name} {method.Name}({string.Join(", ", method.GetParameters().Select(p => $"{p.ParameterType.Name} {p.Name}"))})");
Console.WriteLine("\n--- Properties ---");
foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
Console.WriteLine($" {prop.PropertyType.Name} {prop.Name} {{ {(prop.CanRead ? "get" : "")} {(prop.CanWrite ? "set" : "")} }}");
Console.WriteLine("\n--- Fields ---");
foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
Console.WriteLine($" {field.FieldType.Name} {field.Name}");
Console.WriteLine("\n--- Events ---");
foreach (var evt in type.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
Console.WriteLine($" {evt.EventHandlerType.Name} {evt.Name}");
}
Type/MethodInfo 或改用委派/Expression TreesNonPublic 存取需 ReflectionPermission,沙箱環境可能受限typeof(List<>) vs 封閉泛型 typeof(List) ,MakeGenericType 動態建構精通 System.Reflection 是開發框架、序列化器、DI 容器、測試工具、程式碼產生器的基礎功力。