首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C#反射避坑指南:那些年我们踩过的"天劫雷"

C#反射避坑指南:那些年我们踩过的"天劫雷"

作者头像
云中小生
发布2025-08-24 09:16:02
发布2025-08-24 09:16:02
8300
代码可运行
举报
运行总次数:0
代码可运行

各位.NET道友大家好,我是.NET修仙日记的掌门人,今天我们就来聊一聊反射(Reflection) ,那么什么是反射(Reflection)呢?接下来就和我一起来探索.NET修仙界的反射(Reflection)神通……

一、反射神通的核心概念

1.1 什么是反射?

在.NET修真界,反射(Reflection)是程序自我探查、自我修改的无上神通。它允许我们在运行时:

  • 探查类型信息(类、结构体、接口等)
  • 动态创建对象实例
  • 调用方法和访问属性
  • 获取和操作特性(Attributes)
  • 动态生成代码(通过Emit)
反射运行时
反射运行时

反射运行时

1.2 核心装配说明

反射的核心装配位于System.Reflection命名空间,主要包含以下关键类型:

类型

说明

常用属性/方法

Assembly

代表程序集

GetTypes(), GetModules()

Module

代表模块

GetTypes(), GetFields()

Type

代表类型

GetMethods(), GetProperties()

MethodInfo

方法信息

Invoke(), ReturnType

PropertyInfo

属性信息

GetValue(), SetValue()

FieldInfo

字段信息

GetValue(), SetValue()

2.基础反射操作

2.1 获取类型信息

代码语言:javascript
代码运行次数:0
运行
复制
// 三种获取Type对象的方式
Type t1 = typeof(string);          // 通过typeof运算符
Type t2 = Type.GetType("System.String"); // 通过类型名称
Type t3 = "hello".GetType();       // 通过实例获取

Console.WriteLine($"类型名称:{t1.Name}");
Console.WriteLine($"命名空间:{t1.Namespace}");
Console.WriteLine($"是类吗?{t1.IsClass}");
Console.WriteLine($"基类型:{t1.BaseType}");

2.2 动态创建实例

动态创建实例示意图
动态创建实例示意图

动态创建实例示意图

代码语言:javascript
代码运行次数:0
运行
复制
// 创建不同类型的实例
object list = Activator.CreateInstance(typeof(List<string>));
object dt = Activator.CreateInstance(typeof(DateTime), 2023, 1, 1);

// 带参数的构造
Type sbType = typeof(StringBuilder);
StringBuilder sb = (StringBuilder)Activator.CreateInstance(
    sbType, 
    new object[] { "初始值", 100 });

3.高级反射技巧

3.1 方法调用

代码语言:javascript
代码运行次数:0
运行
复制
// 获取并调用方法
Type mathType = typeof(Math);
MethodInfo maxMethod = mathType.GetMethod("Max", 
    new[] { typeof(int), typeof(int) });

int result = (int)maxMethod.Invoke(null, new object[] { 5, 10 });
Console.WriteLine($"最大值:{result}"); // 输出10

3.2 属性操作

属性操作示意图
属性操作示意图

属性操作示意图

代码语言:javascript
代码运行次数:0
运行
复制
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// 反射操作属性
Person p = new Person();
Type personType = typeof(Person);

PropertyInfo nameProp = personType.GetProperty("Name");
nameProp.SetValue(p, "张三");

PropertyInfo ageProp = personType.GetProperty("Age");
ageProp.SetValue(p, 25);

Console.WriteLine($"{p.Name}, {p.Age}岁");

4.特性(Attribute)处理

4.1 自定义特性

代码语言:javascript
代码运行次数:0
运行
复制
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, 
    AllowMultiple = true)]
public class CultivationStageAttribute : Attribute
{
    public string Stage { get; }
    public int RequiredLevel { get; set; }
    
    public CultivationStageAttribute(string stage)
    {
        Stage = stage;
    }
}

4.2 特性探查

特性探查示意图
特性探查示意图

特性探查示意图

代码语言:javascript
代码运行次数:0
运行
复制
[CultivationStage("金丹期", RequiredLevel = 5)]
public class GoldenCoreTechnique
{
    [CultivationStage("小成")]
    public void Practice() { }
}

// 探查特性
Type techniqueType = typeof(GoldenCoreTechnique);

// 类级别特性
var classAttributes = techniqueType.GetCustomAttributes(
    typeof(CultivationStageAttribute), false);
foreach(CultivationStageAttribute attr in classAttributes)
{
    Console.WriteLine($"修炼阶段:{attr.Stage},要求等级{attr.RequiredLevel}");
}

// 方法级别特性
MethodInfo method = techniqueType.GetMethod("Practice");
var methodAttributes = method.GetCustomAttributes(
    typeof(CultivationStageAttribute), false);
// ...类似处理

5.性能优化

5.1 性能对比

性能对比示意图
性能对比示意图

性能对比示意图

5.2 优化策略

策略1:缓存反射对象
代码语言:javascript
代码运行次数:0
运行
复制
private static readonly Type _cachedType = typeof(MyClass);
private static readonly MethodInfo _cachedMethod = _cachedType.GetMethod("MyMethod");
策略2:使用委托
代码语言:javascript
代码运行次数:0
运行
复制
MethodInfo method = typeof(MyClass).GetMethod("MyMethod");
var del = (Func<MyClass, int>)Delegate.CreateDelegate(
    typeof(Func<MyClass, int>), method);

int result = del(myInstance); // 比Invoke快10倍
策略3:表达式树编译
代码语言:javascript
代码运行次数:0
运行
复制
var param = Expression.Parameter(typeof(MyClass));
var call = Expression.Call(param, method);
var lambda = Expression.Lambda<Func<MyClass, int>>(call, param);
var compiled = lambda.Compile(); // 编译成委托

int result = compiled(myInstance); // 接近原生调用性能

6.Emit高级编程

6.1 IL代码生成

IL代码生成
IL代码生成

IL代码生成

6.2 动态方法示例

代码语言:javascript
代码运行次数:0
运行
复制
// 创建动态方法
var dynamicMethod = new DynamicMethod(
    "DynamicAdd",                      // 方法名
    typeof(int),                       // 返回类型
    new[] { typeof(int), typeof(int) }, // 参数类型
    typeof(Program).Module);           // 关联模块

// 生成IL代码
var il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);   // 加载第一个参数
il.Emit(OpCodes.Ldarg_1);   // 加载第二个参数
il.Emit(OpCodes.Add);       // 执行加法
il.Emit(OpCodes.Ret);       // 返回结果

// 创建并调用委托
var addDel = (Func<int, int, int>)dynamicMethod.CreateDelegate(
    typeof(Func<int, int, int>));

int sum = addDel(5, 7); // 输出12

7.实战应用

7.1 插件系统实现

代码语言:javascript
代码运行次数:0
运行
复制
public interfaceIPlugin
{
    string Name { get; }
    void Execute();
}

public class PluginLoader
{
    public List<IPlugin> LoadPlugins(string path)
    {
        var plugins = new List<IPlugin>();
        
        foreach(string dll in Directory.GetFiles(path, "*.dll"))
        {
            Assembly assembly = Assembly.LoadFrom(dll);
            
            foreach(Type type in assembly.GetTypes())
            {
                if(typeof(IPlugin).IsAssignableFrom(type) && !type.IsAbstract)
                {
                    IPlugin plugin = (IPlugin)Activator.CreateInstance(type);
                    plugins.Add(plugin);
                }
            }
        }
        
        return plugins;
    }
}

7.2 ORM框架示例

代码语言:javascript
代码运行次数:0
运行
复制
public class EntityMapper<T> whereT : new()
{
    public T Map(DbDataReader reader)
    {
        T entity = new T();
        Type type = typeof(T);
        
        for(int i = 0; i < reader.FieldCount; i++)
        {
            string name = reader.GetName(i);
            PropertyInfo prop = type.GetProperty(name);
            
            if(prop != null && !reader.IsDBNull(i))
            {
                object value = reader.GetValue(i);
                prop.SetValue(entity, value);
            }
        }
        
        return entity;
    }
}

8.最佳实践

8.1 反射使用准则

  1. 避免滥用:只在真正需要动态行为的场景使用
  2. 性能敏感:高频调用路径避免使用反射
  3. 安全考虑:反射可以绕过访问限制,需谨慎
  4. 缓存优化:重复使用的反射对象要缓存
  5. 错误处理:反射调用要做好异常处理

8.2 替代方案

场景

反射方案

替代方案

动态创建对象

Activator.CreateInstance

工厂模式

方法调用

MethodInfo.Invoke

委托/接口

属性访问

PropertyInfo.Get/Set

动态表达式

插件系统

反射加载

DI容器

附录:常用反射工具方法

代码语言:javascript
代码运行次数:0
运行
复制
public static class ReflectionUtil
{
    // 获取友好类型名称
    public static string GetFriendlyTypeName(Type type)
    {
        if(!type.IsGenericType) return type.Name;
        
        string name = type.Name.Split('`')[0];
        var args = type.GetGenericArguments()
                     .Select(t => GetFriendlyTypeName(t));
        return $"{name}<{string.Join(",", args)}>";
    }
    
    // 深度克隆对象
    public static T DeepClone<T>(T obj)
    {
        if(obj == null) return default;
        
        Type type = obj.GetType();
        if(type.IsValueType || type == typeof(string))
            return obj;
            
        if(type.IsArray)
        {
            Array array = (Array)(object)obj;
            Array cloned = (Array)array.Clone();
            for(int i = 0; i < array.Length; i++)
                cloned.SetValue(DeepClone(array.GetValue(i)), i);
            return (T)(object)cloned;
        }
        
        T clonedObj = (T)Activator.CreateInstance(type);
        foreach(FieldInfo field in type.GetFields(
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
        {
            field.SetValue(clonedObj, DeepClone(field.GetValue(obj)));
        }
        
        return clonedObj;
    }
}

结语

"反射之道,始于探查,精于动态,成于性能。初窥门径易,登堂入室难。望诸君勤加修炼,早日渡劫飞升!" ——.NET修仙日记

(点击关注,修炼不迷路👇

▌转载请注明出处,渡人渡己

🌟 感谢道友结缘! 若本文助您突破修为瓶颈,不妨[打赏灵丹]或[转发功德],让更多.NET道友共参.NET天道玄机。修真之路漫漫,我们以代码为符,共绘仙途!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 .NET修仙日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、反射神通的核心概念
    • 1.1 什么是反射?
    • 1.2 核心装配说明
  • 2.基础反射操作
    • 2.1 获取类型信息
    • 2.2 动态创建实例
  • 3.高级反射技巧
    • 3.1 方法调用
    • 3.2 属性操作
  • 4.特性(Attribute)处理
    • 4.1 自定义特性
    • 4.2 特性探查
  • 5.性能优化
    • 5.1 性能对比
    • 5.2 优化策略
      • 策略1:缓存反射对象
      • 策略2:使用委托
      • 策略3:表达式树编译
  • 6.Emit高级编程
    • 6.1 IL代码生成
    • 6.2 动态方法示例
  • 7.实战应用
    • 7.1 插件系统实现
    • 7.2 ORM框架示例
  • 8.最佳实践
    • 8.1 反射使用准则
    • 8.2 替代方案
  • 附录:常用反射工具方法
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档