---
title: "反射技术"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/csharp-reflection/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/02-编程语言与运行时/.NET与CSharp/反射技术.md"
content_hash: ee83c47eb186bb1f56bb4cbc885c790507aea040a674d80e2b71810eb115fca2
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# 反射技术

> 创建时间：2020/4/28 15:06

OpCodes文档：<https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.emit.opcodes?view=netcore-3.1>

**反射（Reflection）** 是.NET中的重要机制，提供了封装 **程序集** 、 **模块** 和 **类型** 的对象。通过反射，可以在运行时获得.NET中每一个 **类型（包括类、结构、委托、接口和枚举等）的成员** ， **包括方法、属性、事件** ，以 **及构造函数** 等。还可以获得每个 **成员的名称、限定符和参数** 等。有了反射，即可对每一个类型了如指掌。如果获得了构造函数的信息，即可直接创建对象，即使这个对象的类型在编译时还不知道。

程序集信息其实是通过在程序集上应用各种Attribute来设置的，并且这些特性都位于System.Reflection命名空间，也就是这一系列Attribute提供给反射技术，可用于获取程序集的基本信息.
反射则
可以使用反射动态地创建类型的实例，将类型绑定到现有对象或从现有对象中获取类型，然后调用类型的方法或访问其字段和属性。

> 反射的用途：
>  （1）使用Assembly定义和加载程序集，加载在程序集清单中列出模块，以及从此程序集中查找类型并创建该类型的实例。
>  （2）使用Module了解包含模块的程序集以及模块中的类等，还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
>  （3）使用ConstructorInfo了解构造函数的名称、参数、访问修饰符（如pulic 或private）和实现详细信息（如abstract或virtual）等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。
>  （4）使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符（如pulic 或private）和实现详细信息（如abstract或virtual）等。使用Type的GetMethods或GetMethod方法来调用特定的方法。
>  （5）使用FiedInfo了解字段的名称、访问修饰符（如public或private）和实现详细信息（如static）等，并获取或设置字段值。
>  （6）使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等，添加或移除事件处理程序。
>  （7）使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等，获取或设置属性值。
>  （8）使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数，以及参数在方法签名中的位置等。

动态加载程序集：

  1. 通过程序集的长名称加载，一般用于加载位于全局程序集缓存中的程序集。（.NET框架的类库都位于全局程序集缓存中）（使用GacUtil命令行工具可以获取System程序集的长名称）；

  2. 通过指定的文件加载程序集，通常是.dll或.exe文件。

##### 反射用于获取类型信息

```csharp
string str1 = &quot;test&quot;;
string str2 = &quot;test&quot;;

```

##### 反射还可以在运行阶段动态创建类型实例，然后就可以动态调用实例的成员。

方法一：使用Activator类的CreateInstance静态方法，其中方法返回的对象就是对应的实例引用。

```csharp
string str1 = &quot;test&quot;;
string str2 = &quot;test&quot;;

```

方法二：通过反射找出类型的构造函数，然后调用构造函数来获取实例引用。

```csharp
string str1 = &quot;test&quot;;
string str2 = &quot;test&quot;;

```
