【.NET Core】反射(Reflection)详解(三)

【.NET Core】反射(Reflection)详解(三)

文章目录

  • 【.NET Core】反射(Reflection)详解(三)
    • 一、概述
    • 二、ConstructorInfo类
      • 2.1 ConstructorInfo.MemberType 属性
      • 2.2 ConstructorInfo.Invoke 方式
    • 三、MethodInfo类
      • 3.1 获取MethodInfo的方法
      • 3.2 MethodInfo常用属性
      • 3.3 MethodInfo常用方法
    • 四、FieldInfo类
      • 4.1 获取FieldInfo类方法
      • 4.2 FieldInfo常用属性
      • 4.3 FieldInfo常用方法
    • 五、PropertyInfo类
      • 5.1 获取PropertyInfo类方法
      • 5.2 PropertyInfo主要属性
      • 5.3 PropertyInfo主要方法
    • 五、总结

一、概述

反射提供了对已封装的程序集、模型和类型的对象一种动态访问方法。反射包含动态加载程序集的Assembly类、程序集中模块访问的Module类、对类信息Type类、构造函数信息ConstructorInfo类、方法信息MethodInfo类、字段信息FieldInfo类、事件信息EventInfo类、属性信息PropertyInfo类、参数信息ParameterInfo类。博文《反射(Reflection)详解(一)》已详细讲解了Assembly类、Module类的用法。博文《反射(Reflection)详解(三)》详细讲解反射的入口Type。本文将重点讲解反射中的构造、方法、字段、事件及其属性信息等

二、ConstructorInfo类

使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等

Type type = typeof(ReflectionCLS);
ConstructorInfo constructorInfo= type.GetConstructor(new Type[] { typeof(string)});
ReflectionCLS reflection  =(ReflectionCLS) constructorInfo.Invoke(new object[] {"No" });
string no = reflection.No;
Console.WriteLine(no);
ConstructorInfo constructor1=type.GetConstructor(new Type[] { typeof(string) ,typeof(string)});
ReflectionCLS reflections = (ReflectionCLS)constructor1.Invoke(new object[] { "No1", "Code" });
no = reflections.No;
string code = reflections.Code;
Console.WriteLine(no);
Console.WriteLine(code);

2.1 ConstructorInfo.MemberType 属性

获取MemberTypes值,该值指示此成员是构造函数。

2.2 ConstructorInfo.Invoke 方式

调用反射后的构造函数,初始化类

三、MethodInfo类

发现方法的属性并提供对方法元数据的访问。MethodInfo类表示类型的方法。你可以使用MethodInfo对象获取有关对象所表示的方法的信息,以及调用方法。比如:

  • 可以通过检索IsFamilyAndAssemblyIsFamilyOrAssemblyIsPrivate和属性的值来确定该方法的可见性IsPublic
  • 可以通过检索属性的值Attributes或调用方法来发现应用于方法的特性GetCustomAttributes
  • 通过检索和属性的值,可以确定方法是泛型方法,开放式构造泛型方法还是封闭式构造泛型方法IsGenericMethodContainsGenericParameters
  • 可以从GetParameters方法和ReturnParameterReturnType和属性获取有关方法的参数和返回类型的信息。
  • 可以通过调用方法对类实例执行方法Invoke
  • 通过调用方法。可以实例化MethodInfo表示泛型方法定义的构造泛型方法的对象MakeGenericMethod

3.1 获取MethodInfo的方法

  1. Type.GetMethod(String)获取该类的指定的名称String公开的函数方法。如果方法为私有则返回为Null。
  2. Type.GetMethod(String,BindingFlags)获取该类的指定的名字String和指定类型BindingFlags的函数方法。
  3. Type.GetMethods() 获取该类的所有公共的函数方法。
  4. Type.GetMethods(BindingFlags)获取该类的所有指定类型BinddingFlags的函数方法。

3.2 MethodInfo常用属性

  • MethodInfo.MemberInfo属性

    只读属性获取一个MemberTypes值,该值指示成员是方法。

  • MethodInfo.ReturnParameter属性

    获取一个ParameterInfo对象,该对象包含有关方法的返回类型的信息。

  • MethodInfo.ReturnType属性

    获取此方法的返回类型。

  • MethodInfo.ReturnTypeCustomAttributes属性

    获取返回类型的自定义属性。

3.3 MethodInfo常用方法

  • MethodInfo.GetBaseDefinition方法

    当在派生类中被重写时,为直接或间接的基类(用该实例表示的方法首先在此类中声明)上的方法返回MethodInfo对象。

    Type type = Type.GetType("GoyeerConsoleAssertApp.Entity.MachineDemo");
    MethodInfo memberInfo = type.GetMethod("Method1");
    MethodInfo mb = memberInfo.GetBaseDefinition();
    Console.WriteLine($"{memberInfo.ReflectedType.FullName}父类方法{mb.ReflectedType.FullName}");
    

    输出结果

    AwinicConsoleAssertApp.Entity.MachineDemo父类方法AwinicConsoleAssertApp.Entity.BaseClass
    
  • MethodInfo.GetGenericArguments方法

    返回Type对象的数组,这些对象表示泛型方法的类型实参或泛型方法定义的类型形参。

    Type type = Type.GetType("GoyeerConsoleAssertApp.Entity.MachineDemo");
    MethodInfo memberInfo = type.GetMethod("Method1");
    Type[] types = memberInfo.GetGenericArguments ();
    foreach (Type tParam in types) 
    {if (tParam.IsGenericTypeParameter) {Console.WriteLine("\t\t{0}  parameter position {1}" +"\n\t\t   declaring method: {2}",tParam,tParam.GenericParameterPosition,tParam.DeclaringMethod);}
    }
    

    返回数组的元素按它们在泛型方法的类型参数列表中出现的顺序排列

    1、如果当前方法是封闭的构造方法(既GetGenericArguments属性返回false),则该方法返回GetGenericArguments的数组包含已分配给泛型方法定义的泛型类型参数的类型。

    2、如果当前方法是泛型方法定义,则数组包含类型参数。

    3、如果当前方法是打开的构造方法,其中特定类型已分配给某些类型参数,而封闭泛型类型的类型参数已分配给其他类型参数,则数组同时包含类型和类型参数。

  • MethodBase.GetParameters方法

    当在派生类中重写时,获取指定的方法的参数。

    返回值 ParameterInfo[]

    ParameterInfo类型的数组,包含与此MethodBase实例所反射的方法签名匹配的信息。

    Type type = Type.GetType("GoyeerConsoleAssertApp.Entity.MachineDemo");
    MethodInfo memberInfo = type.GetMethod("Method1");
    ParameterInfo[] parameterInfos = memberInfo.GetParameters ();
    foreach (ParameterInfo parameter in parameterInfos) 
    {Console.WriteLine(parameter.Name);  
    }
    
  • MethodBase.Invoke 方法

    调用由此MethodInfo实例反射的方法或构造函数。

    1、Invoke(Object,Object[]) 使用指定参数调用由当前实例表示的方法或构造函数。

    参数一 Object: 在其上调用方法或构造函数的对象。如果方法是静态的,则忽略此参数。如果构造函数是静态的,则此参数必须是null或定义构造函数的类的实例。

    参数二 Object[] 调用方法或构造函数的参数列表。此对象数组在数量、顺序和类型方面与要调用的方法或构造函数的参数相同。如果不存在任何参数,则parameters应为null。

    返回值 Object 一个包含已调用方法的返回值或包含已调用构造函数的null的对象。

    Type type = Type.GetType("GoyeerConsoleAssertApp.Entity.MachineDemo");
    //在其上调用方法或构造函数的对象
    ConstructorInfo magicConstructor = type.GetConstructor(Type.EmptyTypes);
    object magicClassObject = magicConstructor.Invoke(new object[] { });
    MethodInfo memberInfo = type.GetMethod("Method1");
    //多用参数集合
    memberInfo?.Invoke(magicClassObject, new object[] { "Param1", "Param2", "Param3", 40 });
    

    2、Invoke(Object,BindingFlags,Binder,Object[],CultureInfo) 当在派生类中重写时,调用具有给定参数的反射的方法或构造函数。

    参数

    obj Object

    在其上调用方法或构造函数的对象。如果方法是静态的,则忽略此参数。如果构造函数是静态,则此参数必须是null或定义构造函数的类的实例。

    invokeAttr BindingFlags

    位屏蔽,它是BindingFlags的0个或多个位标志的组合。如果bindernull,则此参数赋值为Default;因此,传入的任何值都被忽略。

    binder Binder

    一个对象,它启用绑定、对自变量类型的强制、对成员的调用,以及通过反射对MemberInfo对象的检索。如果bindernull,则使用默认联编程序。

    parameters Object[]

    调用方法或构造函数的参数列表。此对象数组在数量、顺序和类型方面与要调用的方法或构造函数的参数相同。如果没有参数,则此应为null

    如果此实例表示的方法或构造函数采用 ByRef 参数,那么使用此函数调用该方法或构造函数时,对于该参数不需要特殊的特性。 此数组中未使用值显式初始化的任何对象都将包含该对象类型的默认值。 对于引用类型元素,此值为null

    culture CultureInfo

    用于控制类型强制CultureInfo的实例。如果这是null,则使用当前线程的CultureInfo

    返回

    object,包含被调用方法的返回值;如果调用的是构造函数,则为null;如果方法的返回类型是null,则为void在调用方法或构造函数之前,Invoke检查用户是否有访问权限并验证参数是否有效。

四、FieldInfo类

发现字段的属性并提供对字段元数据的访问权限。字段信息是从元数据获取的。类FieldInfo没有公共构造函数。FieldInfo对象是通过调用GetFields对象的或GetField方法获取的Type。字段是在类中定义的变量。FieldInfo提供对类中字段元数据的访问,并为字段提供动态集和获取功能。在对象上调用invoke或get之前,类不会加载得到内存中。

4.1 获取FieldInfo类方法

  • GetField(string) 获取当前Type的特定字段。
  • GetFields() 获取FieldInfo集合。
Type type = Type.GetType("AwinicConsoleAssertApp.Entity.MachineDemo");
FieldInfo fieldInfo = type.GetField("FieldA");
Console.WriteLine($"FieldInfo={fieldInfo.Name}");
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{Console.WriteLine($"FieldInfo的Name={field.Name}");
}

4.2 FieldInfo常用属性

  • IsPrivate 获取一个值,通过该值指示此字段是否为私有字段。
  • IsPublic 获取一个值,通过该值指示此字段是否为公共字段。
  • IsStatic 获取一个值,通过该值指示此字段是否为静态字段。
  • Name 获取当前成员的名称。

4.3 FieldInfo常用方法

  • FieldInfo.GetValue(Object)方法

    当在派生类中重写时,返回给定对象支持的字段的值。

    FieldInfo fld = typeof(Example).GetField("val");
    Console.WriteLine(fld.GetValue(null));
    val = "hi";
    Console.WriteLine(fld.GetValue(null));
    
  • FieldInfo.SetValue(Object?,Object?)方法

    将给定对象的字段值设置为给定值。

    Example myObject = new Example();
    Type myType = typeof(Example);
    FieldInfo myFieldInfo = myType.GetField("myString",BindingFlags.NonPublic | BindingFlags.Instance);
    Console.WriteLine($"The field value of myString is {myFieldInfo.GetValue(myObject)}.");
    myFieldInfo.SetValue(myObject, "New value");
    Console.WriteLine($"The field value of mystring is myFieldInfo.GetValue(myObject).");
    

五、PropertyInfo类

发现属性(Property)的属性(Attribute)并提供对属性(Property)元数据的访问。

5.1 获取PropertyInfo类方法

  • GetProperty(string) 返回PropertyInfo System.Type 实例,表示当前实例的确切运行时类型。

  • GetProperties() 返回: PropertyInfo[] 表示当前 System.Type 的所有公共属性的 System.Reflection.PropertyInfo 对象数组。

    或 -如果当前 System.Type 没有公共属性,则为 System.Reflection.PropertyInfo 类型的空数组。

5.2 PropertyInfo主要属性

  • CanRead

    获取一个值,该值指示是否可读属性。

  • CanWrite

    获取一个值,该值指示是否可写属性。

  • GetMethod

    获取属性的Get访问器

Type MyTypea = Type.GetType("Mypropertya");
PropertyInfo Mypropertyinfoa = MyTypea.GetProperty("Caption");
Type MyTypeb = Type.GetType("Mypropertyb");
PropertyInfo Mypropertyinfob = MyTypeb.GetProperty("Caption");// Get and display the CanWrite property.
Console.Write("\nCanWrite a - " + Mypropertyinfoa.CanRead);
Console.Write("\nCanWrite b - " + Mypropertyinfob.CanWrite);

5.3 PropertyInfo主要方法

  • PropertyInfo.GetValue 方法

    返回指定对象的属性值。

  • PropertyInfo.SetValue 方法

    设置指定对象的属性值。

string test = "abcdefghijklmnopqrstuvwxyz";
PropertyInfo pinfo = typeof(string).GetProperty("Chars");
for (int x = 0; x < test.Length; x++)
{Console.Write(pinfo.GetValue(test, new Object[] {x}));
}Console.WriteLine();

五、总结

程序通过类创建对象,反射将这一过程进行反转,通过实例化对象来获取所属类的信息。

作用:在程序运行状态时,构造任意一个类的对象、获取任意一个对象所属的类的信息、调用任意一个类的成员变量和方法、获取任意一个对象的属性和方法。

优点:可以在程序运行期间动态的创建和编译对象,不需要再次重新编译,就可以更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/578097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于5G智能网关的智慧塔吊监测方案

塔吊是建筑施工中必不可少的设施&#xff0c;由于塔吊工作重心高、起重载荷大、人工视距/视角受限等因素&#xff0c;也使得塔吊在工作过程中着较多的危险因素。对此&#xff0c;可以部署基于工业5G智能网关搭建智慧塔吊安全监测系统&#xff0c;实现对塔吊运行的全局精细监测感…

TP-Link路由器桥接设置

本文介绍了TP-Link路由器无线桥接设置方法&#xff1b;无线桥接指的就是通过无线的方式&#xff0c;把两台(多台)无线路由器连接起来&#xff0c;进行桥接的几台路由器中&#xff0c;只要有一台可以上网&#xff0c;剩下的也就可以上网了&#xff1b;主要作用是用来扩大无线WiF…

【STM32单片机】电子木鱼设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103/F407单片机控制器&#xff0c;TFTLCD触摸屏、蜂鸣器等。 主要功能&#xff1a; 系统运行后&#xff0c;TFTLCD显示画面&#xff0c;可触摸木鱼区域&#xff0c;功德计数加1&#xf…

漏刻有时数据可视化Echarts组件开发(46)散点图颜色判断

series组件 series: [{name: Top 5,type: scatter,coordinateSystem: bmap,data: convertData(data.sort(function (a, b) {return b.value - a.value;}).slice(0, 6)),symbolSize: 20,encode: {value: 2},showEffectOn: render,rippleEffect: {brushType: stroke},label: {fo…

分布式系统架构设计之分布式通信机制

二、分布式通信机制&#xff1a;保障系统正常运行基石 在分布式系统中&#xff0c;各个组件之间的通信是保障系统正常运行的基石&#xff0c;直接影响到系统的性能、可扩展性以及整体的可维护性。接下来我们就一起看看通信在分布式系统中的重要性&#xff0c;以及一些常用的技…

Java---IO流讲解(2)

文章目录 1. 字符流1.1 为什么出现字符流1.2 字符流写数据的5种方式1.3 字符流读数据的两种方式1.4 字符缓冲流1.5 字符缓冲流特有功能 2. IO流小结2.1 字节流2.2 字符流 1. 字符流 1.1 为什么出现字符流 由于字节流操作中文时不是特别方便&#xff0c;因此Java提供了字符流。…

SpringBoot - Maven 打包合并一个胖 JAR 以及主项目 JAR 依赖 JAR 分离打包解决方案

问题描述 <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.1.18.RELEASE</version><configuration><!--<classifier>exec</classifier>--…

JS常用HOOK调试技术

hook技术 Hook 是一种钩子技术&#xff0c;在系统没有调用函数之前&#xff0c;钩子程序就先得到控制权&#xff0c;这时钩子函数既可以加工处理&#xff08;改变&#xff09;该函数的执行行为&#xff0c;也可以强制结束消息的传递。简单来说&#xff0c;修改原有的 JS 代码就…

网络安全保障流程

需求定义 满足法规合规、业务需求、风险评估 信息系统保护轮廓ISPP-----标准化安全保障需求文档----从用户角度规范化、机构化 需要包括&#xff1a;系统描述、安全环境、保障目的、安全保障要求、应用注解、符合性声明7部分 规划设计 考虑业务功能和价值&#xff0c;哪些风险…

12.25广义分布外检测学习/代码复现

A model.getA().toarray() # b np.array(model.RHS) sense np.array(model.sense) f np.array(model.obj)Aineq np.vstack((-Ale, Age)) # 把所有的<和>组合在一起 bineq np.append(-ble, bge) # 这里用append使bineq为一个一维矩阵&#xff0c;而不是2行1列的二…

html动态加载script

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>动态添加JavaScript代码</title> </head> <body> <h1>Hello, World!</h1> <button onclick"add…

SpringBoot 3.2.0 基于Spring Security+JWT实现动态鉴权

依赖版本 JDK 17 Spring Boot 3.2.0 Spring Security 6.2.0 工程源码&#xff1a;Gitee 为了能够不需要额外配置就能启动项目&#xff0c;看到配置效果。用例采用模拟数据&#xff0c;可自行修改为对应的ORM操作 编写Spring Security基础配置 导入依赖 <properties>&l…

Pikachu靶场 字符型SQL注入

在Pikachu靶场里查询 xx or 11 # or 11 # union select username,password from users# 在 MySQL 的 bin 路径下打开 cmd &#xff0c;输入下面的命令&#xff0c;再输入 数据库的密码 mysql -u root -p 执行命令 show databases; use pikachu show tables; desc member; s…

《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识(1)

前言中曾提到&#xff1a;本章主要说明PCI总线涉及的一些基本知识。 PCI总线作为处理器系统的本地总线&#xff0c;其主要目的是为了连接外部设备&#xff0c;而不是作为处理器的系统总线连接Cache和主存储器。但是PCI总线、系统总线和处理器体系结构之间依然存在着紧密的联系…

java练习之abstract (抽象) final(最终) static(静态) 练习

1&#xff1a;分析总结&#xff1a;写出private、abstract、static、final之间能否联动使用&#xff0c;并写出分析原因 private static final 之间可以任意结合 abstract 不可以与private static final 结合使用 2&#xff1a;关于三个修饰符描述不正确的是(AD) A. static …

Linux操作系统基础知识点

Linux是一种计算机操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年首次发布。Linux操作系统通常与GNU套件一起使用&#xff0c;因此也被称为GNU/Linux。它是一种类UNIX的操作系统&#xff0c;设计为多用户、多任务…

计算机组成原理综合6

补码表示&#xff1a; X&#xff1a;1111 1111 1111 1101 Y&#xff1a;1111 1111 1101 1111 Z&#xff1a;0111 1111 1111 1100 转原码表示&#xff1a;从右往左找第一个“1”&#xff0c;左边的所有数值位按位取反 X&#xff1a;1111 1111 1111 1101 1000 0000 00…

常用的快捷键

快捷键能大大提高使用计算机时的效率。以下是一些常用的快捷键&#xff0c;适用于多种操作系统和应用程序&#xff1a; 通用快捷键 复制: Ctrl C (Windows/Linux) | Cmd C (Mac) 粘贴: Ctrl V (Windows/Linux) | Cmd V (Mac) 剪切: Ctrl X (Windows/Linux) | Cmd X (Ma…

Fiber Node的数据结构,以及如何在Reconciliation阶段被使用。

首先&#xff0c;Fiber Node是React用来描述组件树的数据结构&#xff0c;每一个React组件都对应一个Fiber Node。下面是一个Fiber Node的基本结构&#xff1a; const fiber {// 标识这个Fiber Node的类型&#xff08;函数组件&#xff0c;类组件&#xff0c;DOM节点类型等&a…

OGG-MySQL无法正常同步数据问题分析

问题背景: 用户通过OGG从源端一个MySQL从库将数据同步到目标端的另一个MySQL数据库里面&#xff0c;后面由于源端的从库出现了长时间的同步延时&#xff0c;由于延时差距过大最后选择通过重建从库方式进行了修复 从库重建之后&#xff0c;源端的OGG出现了报错ERROR OGG-0014…