.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 命名空间的类提供一种专用形式的反射,使你能够在运行时生成类型。

相关推荐
信号处理学渣19 分钟前
matlab画图,选择性显示legend标签
开发语言·matlab
红龙创客20 分钟前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
jasmine s29 分钟前
Pandas
开发语言·python
biomooc1 小时前
R 语言 | 绘图的文字格式(绘制上标、下标、斜体、文字标注等)
开发语言·r语言
骇客野人1 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言
black^sugar1 小时前
纯前端实现更新检测
开发语言·前端·javascript
404NooFound1 小时前
Python轻量级NoSQL数据库TinyDB
开发语言·python·nosql
用余生去守护2 小时前
python报错系列(16)--pyinstaller ????????
开发语言·python
数据小爬虫@2 小时前
利用Python爬虫快速获取商品历史价格信息
开发语言·爬虫·python
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎