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

C# 反射命名空間 System.Reflection 核心類型與 Type 類別詳解

     編輯:關於C語言

前言

反射是 .NET 執行期型別發現機制,允許程式碼檢查、操作組件、模組、型別、成員的中繼資料。本文系統整理 System.Reflection 命名空間核心類型、System.Type 類別關鍵成員、以及取得 Type 實例的三種方式。

System.Reflection 核心類型架構

類型用途關鍵屬性/方法
Assembly載入、檢查、操作組件GetTypes(), GetName(), Load()
AssemblyName組件身分資訊 (版本、文化特性、強名稱)Version, CultureInfo, GetPublicKey()
EventInfo事件中繼資料EventHandlerType, AddEventHandler()
FieldInfo欄位中繼資料FieldType, GetValue(), SetValue()
MethodInfo方法中繼資料ReturnType, GetParameters(), Invoke()
ParameterInfo參數中繼資料ParameterType, Name, Position
PropertyInfo屬性中繼資料PropertyType, GetValue(), SetValue()
MemberInfo抽象基類,定義共同行為Name, DeclaringType, MemberType, GetCustomAttributes()
Module多檔案組件中的模組存取GetTypes(), Assembly

MemberInfo 繼承階層


MemberInfo (abstract)
├── EventInfo
├── FieldInfo
├── MethodBase (abstract)
│   ├── ConstructorInfo
│   └── MethodInfo
├── PropertyInfo
└── Type (繼承 MemberInfo,也代表型別本身)

System.Type 核心成員分類

1. 型別檢查屬性


IsAbstract, IsClass, IsValueType, IsInterface, IsEnum, 
IsArray, IsGenericType, IsGenericTypeDefinition,
IsPublic, IsPrivate, IsSealed, IsStatic, ...

2. 成員取得方法


// 單數版本:取得單一成員
GetConstructor(), GetEvent(), GetField(), GetMethod(), GetProperty()

// 複數版本:取得成員陣列
GetConstructors(), GetEvents(), GetFields(), GetMethods(), GetProperties()

// 統一查詢
FindMembers(MemberTypes, BindingFlags, MemberFilter, object)
GetMembers(BindingFlags)

3. 靜態工廠方法


// 從字串取得型別 (需完整命名空間)
Type.GetType("System.String")                    // mscorlib
Type.GetType("MyNamespace.MyClass, MyAssembly")  // 指定組件

4. 晚期繫結呼叫


// 呼叫方法、存取屬性/欄位、建構實例
InvokeMember(string name, BindingFlags, Binder, object target, object[] args)

取得 Type 實例的三種方式

方式 1:Object.GetType() — 從實例取得


Person p = new Person();
Type t = p.GetType();  // 最常用,執行期確切型別

方式 2:typeof 運算子 — 從編譯期型別取得


Type t1 = typeof(Person);
Type t2 = typeof(List);
Type t3 = typeof(Dictionary<,>);  // 開放泛型型別定義

方式 3:Type.GetType(string) — 從字串取得


// 完整型別名稱:命名空間.類別名, 組件名稱
Type t = Type.GetType("MyApp.Models.Person, MyApp");

// 僅型別名稱:僅搜尋 mscorlib 與目前執行組件
Type t = Type.GetType("Person");  // 可能回傳 null

實務應用範例:動態建構物件並呼叫方法


public static object CreateAndInvoke(string typeName, string methodName, params object[] args)
{
    // 1. 取得型別
    Type type = Type.GetType(typeName);
    if (type == null) throw new ArgumentException($"找不到型別: {typeName}");
    
    // 2. 建構實例 (呼叫無參數建構子)
    object instance = Activator.CreateInstance(type);
    
    // 3. 取得方法資訊
    MethodInfo method = type.GetMethod(methodName);
    if (method == null) throw new ArgumentException($"找不到方法: {methodName}");
    
    // 4. 呼叫方法
    return method.Invoke(instance, args);
}

// 使用
var result = CreateAndInvoke("MyApp.Services.Calculator", "Add", 10, 20);
// 相當於: new Calculator().Add(10, 20)

效能考量與快取策略

  • Type.GetType()、GetMethod()、GetProperty() 等反射操作較慢
  • 熱點路徑應快取 MemberInfo 物件 (MethodInfo、PropertyInfo 等)
  • 高效能場景考慮 Expression Tree、DynamicMethod、Source Generators 替代

總結

System.Reflection 提供完整的中繼資料操作能力。核心在於 Type 類別作為入口,透過 MemberInfo 衍生類別存取具體成員。理解三種取得 Type 的方式、單數/複數成員查詢方法、晚期繫結 InvokeMember,是反射程式設計的基礎。實務中務必注意效能,善用快取與替代方案。

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