LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# 反射(Reflection)核心详解,让代码看起来更厉害的样子

admin
2025年12月14日 17:18 本文热度 832

反射(Reflection)是 C# 中一种‌动态分析程序集、类型及成员‌的机制,允许在‌运行时‌获取类型信息、创建对象、调用方法或访问字段,无需在编译时明确知道具体类型。

一、‌反射的核心功能‌

1‌、动态类型操作‌

  • 获取类型信息(类、接口、结构体等)。
  • 实例化对象、调用方法、读写字段/属性。

2‌、程序集分析‌

  • 加载外部程序集(DLL),遍历其包含的类型和成员。

3‌、元数据访问‌

  • 读取特性(Attribute)、泛型参数、方法签名等元数据。

二、‌核心类与用法‌

1‌、System.Type 类‌

‌获取类型的途径‌:

// 通过对象获取  
Type type1 = obj.GetType();

// 通过类型名获取  
Type type2 typeof(int);
Type type3 = Type.GetType("System.String");

// 通过程序集获取  
Assembly assembly = Assembly.Load("MyLibrary");
Type type4 = assembly.GetType("MyLibrary.MyClass");

‌常用方法‌:

  • GetMethods():获取所有公共方法。
  • GetProperties():获取所有属性。
  • GetCustomAttributes():读取特性。

2‌、System.Reflection.Assembly 类‌

  • ‌加载程序集‌:
// 从文件加载  
Assembly asm1 = Assembly.LoadFrom("MyLibrary.dll");

// 通过程序集名加载  
Assembly asm2 = Assembly.Load("MyLibrary");
  • ‌遍历程序集中的类型‌:
foreach(Type type in asm1.GetTypes())
{
    Console.WriteLine(type.FullName);
}

3‌、Activator 类‌

  • ‌动态创建对象‌:
Type type typeof(MyClass);
object instance = Activator.CreateInstance(type);

// 带参数的构造函数  
object instance2 = Activator.CreateInstance(type,"参数1",100);

4‌、MethodInfo 与调用方法‌

Type type typeof(MyClass);
MethodInfo method = type.GetMethod("MyMethod");
object instance = Activator.CreateInstance(type);

// 调用无参方法  
method.Invoke(instance,null);

// 调用有参方法  
method.Invoke(instance,new object[]{"参数",42});

三、‌典型应用场景‌

1‌、动态插件系统‌

  • ‌加载外部 DLL,实现模块化扩展。
Assembly pluginAsm = Assembly.LoadFrom("Plugin.dll");
Type pluginType = pluginAsm.GetType("Plugin.MyPlugin");
IPlugin plugin (IPlugin)Activator.CreateInstance(pluginType);
plugin.Execute();

2‌、依赖注入(DI)框架‌

  • ‌通过反射自动解析构造函数参数并实例化服务。
public static Resolve<T>()
{
 Type type =typeof(T);
 ConstructorInfo ctor = type.GetConstructors().First();
 ParameterInfo[] paramsInfo = ctor.GetParameters();
 object[] args = paramsInfo.Select(=>Resolve(p.ParameterType)).ToAr ray();
 return (T)ctor.Invoke(args);
}

3‌、序列化与反序列化‌

  • ‌动态读取对象的字段/属性并转换为 JSON 或 XML。
public static string ToJson(object obj)
{
 var sb =new StringBuilder("{");
 foreach(PropertyInfo prop in obj.GetType().GetProperties())
 {
   object value= prop.GetValue(obj);
   sb.Append($"\"{prop.Name}\":\"{value}\",");
 }
   sb.Remove(sb.Length -1,1).Append("}");
   return sb.ToString();
}

4‌、ORM(对象关系映射)‌

  • ‌将数据库查询结果映射到实体类。
public static MapToEntity<T>(DataRow row)whereT:new()
{
 T entity new T();
 foreach(DataColumn column in row.Table.Columns)
 {
  PropertyInfo prop =typeof(T).GetProperty(column.ColumnName);
  if(prop !=null&& row[column]!= DBNull.Value)
  prop.SetValue(entity, row[column]);
}
 return entity;
}

四、‌性能与优化‌

1‌、反射的性能问题‌

  • ‌反射操作(如 Invoke)比直接代码调用慢 ‌10~100 倍‌。
  • ‌频繁使用反射可能导致性能瓶颈。

2‌、优化策略‌

  • ‌缓存反射结果‌:

private static readonly MethodInfo _cachedMethod = typeof(MyClass).GetMethod("MyMethod");  


  • ‌‌使用 Delegate 或 Expression‌:
// 将 MethodInfo 转换为委托  
Action<object,object[]> methodDelegate =(Action<object,object[]>)
    Delegate.CreateDelegate(typeof(Action<object,object[]>), _cachedMethod);
  • ‌‌预编译表达式树‌:
var param = Expression.Parameter(typeof(MyClass));
var call = Expression.Call(param, _cachedMethod);
var lambda = Expression.Lambda<Action<MyClass>>(call, param).Compile();
lambda(obj);// 高速调用  

五、‌反射的局限性‌

1‌、安全性限制‌

  • ‌在部分受信任环境(如沙箱)中,反射可能被限制。
    2‌、破坏封装性‌
  • ‌反射可访问私有成员,过度使用可能导致代码脆弱性。
    3‌、类型强依赖‌
  • ‌动态代码若类型不匹配,会引发运行时异常(而非编译错误)。

总结

C# 反射是处理动态类型和元数据的强大工具,广泛应用于插件系统、序列化、ORM 等场景。尽管其灵活性极高,但需谨慎使用以避免性能问题和代码维护困难。‌优化策略‌(如缓存、表达式树)和‌合理设计‌(如接口隔离)是高效使用反射的关键。


阅读原文:原文链接


该文章在 2025/12/15 9:00:02 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved