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

C# 反射入門核心:Type、Assembly、動態加載與晚綁定

     編輯:關於C#

反射是什麼?

反射 是 .NET 運行時檢查、操作類型中繼資料的機制。核心類位於 System.Reflection:

  • Assembly:程序集,可加載、檢查、創建類型實例
  • Type:類型核心,包含方法、屬性、構造函數、字段等完整描述
  • MethodInfo、PropertyInfo、FieldInfo、ConstructorInfo...:具體成員資訊

一、Type 類:反射的入口

獲取 Type 的三種方式

MyClass obj = new MyClass();

// 1. 實例.GetType()
Type t1 = obj.GetType();

// 2. typeof(類型) - 編譯期已知
Type t2 = typeof(MyClass);

// 3. 字串獲取 - 完全動態
Type t3 = Type.GetType("MyNamespace.MyClass, MyAssembly");

Type 常用屬性與方法

Console.WriteLine($"名稱: {t.Name}");
Console.WriteLine($"完整名: {t.FullName}");
Console.WriteLine($"命名空間: {t.Namespace}");
Console.WriteLine($"程序集: {t.Assembly}");
Console.WriteLine($"基類: {t.BaseType}");
Console.WriteLine($"是否類: {t.IsClass}");

// 獲取所有公共成員
foreach (var m in t.GetMembers())
    Console.WriteLine($"{m.MemberType}: {m.Name}");

二、Assembly:程序集元數據與動態加載

獲取當前程序集資訊

Assembly asm = Assembly.GetExecutingAssembly();
Console.WriteLine($"完整名: {asm.FullName}");
Console.WriteLine($"版本: {asm.GetName().Version}");
Console.WriteLine($"位置: {asm.Location}");
Console.WriteLine($"入口點: {asm.EntryPoint}");

// 列出程序集所有類型
foreach (var type in asm.GetTypes())
    Console.WriteLine($"類型: {type.FullName}");

動態加載外部程序集

// 從文件加載
Assembly asm = Assembly.LoadFrom(@"C:\Libs\MyPlugin.dll");

// 從字節數組加載 (如從資料庫/網絡獲取)
byte[] dllBytes = File.ReadAllBytes("Plugin.dll");
Assembly asm = Assembly.Load(dllBytes);

三、晚綁定:運行時創建實例並調用成員

早綁定 = 編譯期確定類型;晚綁定 = 運行時根據字串決定類型與成員。

完整晚綁定範例

public class Calculator
{
    private readonly int _factor;
    public Calculator(int factor) => _factor = factor;
    public int Multiply(int x) => x * _factor;
}

// Main
Assembly asm = Assembly.GetExecutingAssembly();

// 1. 創建實例 (帶構造函數參數)
object calc = asm.CreateInstance(
    "MyApp.Calculator", 
    false, 
    BindingFlags.ExactBinding, 
    null, 
    new object[] { 5 }, // 構造參數
    null, null);

// 2. 獲取方法資訊
MethodInfo method = asm.GetType("MyApp.Calculator").GetMethod("Multiply");

// 3. 調用方法
object result = method.Invoke(calc, new object[] { 10 });
Console.WriteLine($"結果: {result}"); // 50

四、實用場景對照

場景核心 API說明
插件掃描Assembly.LoadFrom + GetExportedTypes掃描目錄 DLL 載入擴展
配置驅動實例化Type.GetType + Activator.CreateInstance字串名稱創建對象
動態方法調用MethodInfo.Invoke運行時決定調用哪個方法
屬性值獲取/設置PropertyInfo.GetValue/SetValue序列化、映射、綁定核心
自定義特性讀取GetCustomAttributes框架基礎設施

效能與安全提醒

  • 反射比直接調用慢:熱路徑請緩存 MethodInfo/PropertyInfo,或用 Delegate.CreateDelegate 轉為委托
  • BindingFlags 組合控制搜索範圍:Public | NonPublic | Instance | Static | FlattenHierarchy
  • 部分信任環境需 ReflectionPermission
  • 避免在循環中重複 GetType()/GetProperties()

進階:Expression Tree 替代方案

對於頻繁動態調用,System.Linq.Expressions 可在運行時編譯委托,性能接近靜態代碼:

var param = Expression.Parameter(typeof(Calculator), "c");
var call = Expression.Call(param, "Multiply", null, Expression.Constant(10));
var lambda = Expression.Lambda<Func<Calculator, int>>(call, param);
var compiled = lambda.Compile(); // 快速委托
int result = compiled(calc);

反射是 .NET 動態能力的基石,理解 Type/Assembly/晚綁定三大支柱,才能駕馭框架開發與進階架構設計。

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