C#的反射(Reflection)是一套在程序运行期间查看和操控类型信息的机制。借助反射,我们可以在编译时不清楚对象具体类型的情况下,动态获取类、方法、属性等元数据,并创建实例或执行方法。这在开发插件系统、序列化工具和依赖注入容器时非常实用。

什么是反射
反射建立在 System.Reflection 命名空间之上。核心类型是 Type,它描述了一个类的结构。通过 Type 可以拿到类名、基类、接口、字段、方法和特性等信息。
如何动态获取类型信息
常见做法是从程序集入手。下面示例展示如何加载当前程序集并读取某个类型的公开方法:
using System;
using System.Reflection;
public class Demo
{
public void SayHello()
{
Console.WriteLine("Hello from reflection");
}
}
class Program
{
static void Main()
{
// 获取当前执行的程序集
Assembly asm = Assembly.GetExecutingAssembly();
// 根据名称获取类型
Type type = asm.GetType("Demo");
// 输出类型名称
Console.WriteLine(type.FullName);
// 获取所有公开方法
MethodInfo[] methods = type.GetMethods();
foreach (MethodInfo m in methods)
{
Console.WriteLine(m.Name);
}
}
}
如何动态调用方法
拿到 Type 和 MethodInfo 后,可以使用 Activator 创建对象,再用 Invoke 执行方法:
using System;
using System.Reflection;
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
class Program
{
static void Main()
{
Type type = typeof(Calculator);
// 动态创建实例
object instance = Activator.CreateInstance(type);
// 获取 Add 方法
MethodInfo method = type.GetMethod("Add");
// 准备参数
object[] args = new object[] { 3, 5 };
// 调用方法并接收返回值
object result = method.Invoke(instance, args);
Console.WriteLine(result);
}
}
反射的注意事项
- 性能开销:反射调用比直接调用慢,不要在高频循环中滥用。
- 权限问题:某些平台对私有成员访问有限制。
- 可维护性:过度使用反射会让代码难以跟踪类型依赖。
小结
反射让 C# 具备了运行时的灵活扩展能力。掌握 Type、Assembly 与 MethodInfo 的基本用法,就能实现动态获取类型信息和调用方法,为构建通用组件打下基础。