.NET 反射的介绍和简单应用

什么是反射?

反射就是动态发现类型信息的能力。它帮助程序设计人员在程序运行时利用一些信息去动态地使用类型,这些信息在设计时是未知的,这种能力类似于后期绑定。反射还支持的更高级的行为,能在运行时动态创建新类型,并且对这些新类型的操作进行调用。

听起来可能不太清楚,那反射有什么用呢?

  • 在程序运行时,动态加载需要的程序集,以便操作其元数据。(例如有些IOC容器的实现,就是通过配置对应程序集,在运行时动态加载这些程序集,实现注入)
  • 构造出可重用性的代码,通过反射可以动态的绑定/获取数据(例如orm中将查询结果转成实体,在更新数据时需要获取实体信息构造更新语句)

可能还是不太清楚,那下面就通过一个简单的例子来介绍一下:

自定义一个类和特性:

cs 复制代码
    [AttributeUsage(AttributeTargets.Method)]
    public class ApiAttribute : Attribute
    {
        
        public string name;

        public ApiAttribute(string _name) 
        {
            name = _name;
        }
    }


    public class lwpoor
    {
        private int password;
        public string name;
        public lwpoor()
        {

        }

        public lwpoor(string name)
        {
            this.name = name;
        }

        [Api("测试 test")]
        public string test(string username)
        {
            return username;
        }


        public string test1(string username)
        {
            return username;
        }
    }

使用反射调用自定义类:

cs 复制代码
static void Main(string[] args)
{
    Console.WriteLine("Hello, World!");

    var type = typeof(lwpoor);
    //获取所有公共属性
    var pro = type.GetFields();
    foreach (var prop in pro)
    {
        Console.WriteLine($"属性名称:{prop.Name} 类型:{prop.FieldType.Name}");
    }

    //获取类中标注ApiAttribute特性的方法
    var methods = type.GetMethods()
        .Where(p=>p.IsDefined(typeof(ApiAttribute),true)).ToList();

    foreach (var method in methods)
    {
        ApiAttribute? att = method.GetCustomAttribute(typeof(ApiAttribute)) as ApiAttribute;
        Console.WriteLine($"方法名:{method.Name}   说明:{att?.name}");
        //获取方法所有参数
        var parameters = method.GetParameters();
        foreach (var param in parameters)
        {
            Console.WriteLine($"参数名:{param.Name}  参数类型:{param.ParameterType.Name}");
        }
        //创建实例
        var obj = Activator.CreateInstance(type);

        var key = Console.ReadLine();
        //调用方法
        var res = method.Invoke(obj, new object[] { key });
        //获取方法返回类型
        var aa = method.ReturnType.Name;
        Console.WriteLine($"调用方法返回类型:{aa}  返回结果:{res}");
    }

    
}

下面来做个总结:

反射提供封装程序集、模块和类型的对象。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。 然后,可以调用类型的方法或访问其字段和属性。 反射的典型用法如下所示:

  • 使用 Assembly 来定义和加载程序集,加载程序集清单中列出的模块,以及在此程序集中定位一个类型并创建一个它的实例。

  • 使用 Module 发现信息,如包含模块的程序集和模块中的类。 还可以获取所有全局方法或模块上定义的其它特定的非全局方法。

  • 使用 ConstructorInfo 发现信息,如名称、参数、访问修饰符(如 publicprivate)和构造函数的实现详细信息(如 abstractvirtual)。 使用 TypeGetConstructorsGetConstructor 方法来调用特定构造函数。

  • 使用 MethodInfo 发现信息,如名称、返回类型、参数、访问修饰符(如 publicprivate)和方法的实现详细信息(如 abstractvirtual)。 使用 TypeGetMethodsGetMethod 方法来调用特定方法。

  • 使用 FieldInfo 发现信息,如名称、访问修饰符(如 publicprivate)和一个字段的实现详细信息 (如 static);并获取或设置字段值。

  • 使用 EventInfo 发现信息(如名称、事件处理程序的数据类型、自定义特性、声明类型以及事件的反射的类型),并添加或删除事件处理程序。

  • 使用 PropertyInfo 发现信息(如名称、数据类型、声明类型,反射的类型和属性的只读或可写状态),并获取或设置属性值。

  • 使用 ParameterInfo 发现信息,如参数的名称、数据类型、参数是输入参数还是输出参数以及参数在方法签名中的位置。

  • 使用 CustomAttributeData 在于应用程序域的仅反射上下文中工作时发现有关自定义特性的信息。 CustomAttributeData 使你能够检查特性,而无需创建它们的实例。 System.Reflection.Emit 命名空间的类提供一种专用形式的反射,使你能够在运行时生成类型。

相关推荐
Titan20248 小时前
Linux网络学习:套接字、UDP的封装与应用
linux·服务器·开发语言·网络·c++
鸿芯微控科技9 小时前
压电点胶阀出胶量不稳定怎么排查?驱动波形、背压、点胶重量与Python分析
开发语言·python·压电点胶阀·精密点胶·点胶重量·流体控制
原野池予9 小时前
深入Java集合框架:HashMap源码解析(JDK 8)
java·开发语言
测试运维日常笔记9 小时前
VMware vSphere、ESXi 与 vCenter Server:核心概念与关系详解
java·开发语言
m0_5474866610 小时前
《面向对象与Java程序设计》全套PPT课件2026
java·开发语言
星恒随风10 小时前
C++ 红黑树封装(二):迭代器、const_iterator 与 operator[] 完整实现 mymap 和 myset
开发语言·c++·状态模式
jason成都10 小时前
ignav-next|Java 层封装 GNSS/INS 组合导航框架,隔离 RTKLIB 与 INS 内核,双模块独立演进、最小侵入
java·开发语言
抓不住时间的沙10 小时前
butterfly主题美化,打造属于自己的个性博客
java·开发语言·前端·javascript·node.js·github
MarkHD10 小时前
Stable Diffusion入门第19-20天:保存与分享你的工作流——第一阶段收官,从“能用”到“可复用”
java·开发语言·stable diffusion
云水初10 小时前
【agent篇】RAG 知识库构建避坑指南
开发语言·python·学习·agent·rag