{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/csharp-reflection/",
  "atlas": "https://www.pystone.net/?node=csharp-reflection#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/csharp-reflection.md",
  "context": "https://www.pystone.net/notes/csharp-reflection.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:csharp-reflection",
  "slug": "csharp-reflection",
  "title": "反射技术",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "反射技术",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "ee83c47eb186bb1f56bb4cbc885c790507aea040a674d80e2b71810eb115fca2",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "反射技术",
      "anchor": "反射技术",
      "citation": "https://www.pystone.net/notes/csharp-reflection/#%E5%8F%8D%E5%B0%84%E6%8A%80%E6%9C%AF"
    },
    {
      "depth": 5,
      "text": "反射用于获取类型信息",
      "anchor": "反射用于获取类型信息",
      "citation": "https://www.pystone.net/notes/csharp-reflection/#%E5%8F%8D%E5%B0%84%E7%94%A8%E4%BA%8E%E8%8E%B7%E5%8F%96%E7%B1%BB%E5%9E%8B%E4%BF%A1%E6%81%AF"
    },
    {
      "depth": 5,
      "text": "反射还可以在运行阶段动态创建类型实例，然后就可以动态调用实例的成员。",
      "anchor": "反射还可以在运行阶段动态创建类型实例然后就可以动态调用实例的成员",
      "citation": "https://www.pystone.net/notes/csharp-reflection/#%E5%8F%8D%E5%B0%84%E8%BF%98%E5%8F%AF%E4%BB%A5%E5%9C%A8%E8%BF%90%E8%A1%8C%E9%98%B6%E6%AE%B5%E5%8A%A8%E6%80%81%E5%88%9B%E5%BB%BA%E7%B1%BB%E5%9E%8B%E5%AE%9E%E4%BE%8B%E7%84%B6%E5%90%8E%E5%B0%B1%E5%8F%AF%E4%BB%A5%E5%8A%A8%E6%80%81%E8%B0%83%E7%94%A8%E5%AE%9E%E4%BE%8B%E7%9A%84%E6%88%90%E5%91%98"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:programming-languages-and-runtimes",
      "title": "编程语言与运行时",
      "url": "https://www.pystone.net/notes/programming-languages-and-runtimes/",
      "atlas": "https://www.pystone.net/?node=programming-languages-and-runtimes#knowledge-atlas",
      "label": "编程语言与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": ".NET与CSharp中的“反射技术”导航项",
      "citation": "https://www.pystone.net/notes/programming-languages-and-runtimes/#net%E4%B8%8Ecsharp"
    }
  ],
  "contentMarkdown": "# 反射技术\n\n> 创建时间：2020/4/28 15:06\n\nOpCodes文档：<https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.emit.opcodes?view=netcore-3.1>\n\n**反射（Reflection）** 是.NET中的重要机制，提供了封装 **程序集** 、 **模块** 和 **类型** 的对象。通过反射，可以在运行时获得.NET中每一个 **类型（包括类、结构、委托、接口和枚举等）的成员** ， **包括方法、属性、事件** ，以 **及构造函数** 等。还可以获得每个 **成员的名称、限定符和参数** 等。有了反射，即可对每一个类型了如指掌。如果获得了构造函数的信息，即可直接创建对象，即使这个对象的类型在编译时还不知道。\n\n程序集信息其实是通过在程序集上应用各种Attribute来设置的，并且这些特性都位于System.Reflection命名空间，也就是这一系列Attribute提供给反射技术，可用于获取程序集的基本信息.\n反射则\n可以使用反射动态地创建类型的实例，将类型绑定到现有对象或从现有对象中获取类型，然后调用类型的方法或访问其字段和属性。\n\n> 反射的用途：\n>  （1）使用Assembly定义和加载程序集，加载在程序集清单中列出模块，以及从此程序集中查找类型并创建该类型的实例。\n>  （2）使用Module了解包含模块的程序集以及模块中的类等，还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。\n>  （3）使用ConstructorInfo了解构造函数的名称、参数、访问修饰符（如pulic 或private）和实现详细信息（如abstract或virtual）等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。\n>  （4）使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符（如pulic 或private）和实现详细信息（如abstract或virtual）等。使用Type的GetMethods或GetMethod方法来调用特定的方法。\n>  （5）使用FiedInfo了解字段的名称、访问修饰符（如public或private）和实现详细信息（如static）等，并获取或设置字段值。\n>  （6）使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等，添加或移除事件处理程序。\n>  （7）使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等，获取或设置属性值。\n>  （8）使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数，以及参数在方法签名中的位置等。\n\n动态加载程序集：\n\n  1. 通过程序集的长名称加载，一般用于加载位于全局程序集缓存中的程序集。（.NET框架的类库都位于全局程序集缓存中）（使用GacUtil命令行工具可以获取System程序集的长名称）；\n\n  2. 通过指定的文件加载程序集，通常是.dll或.exe文件。\n\n##### 反射用于获取类型信息\n\n```csharp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n##### 反射还可以在运行阶段动态创建类型实例，然后就可以动态调用实例的成员。\n\n方法一：使用Activator类的CreateInstance静态方法，其中方法返回的对象就是对应的实例引用。\n\n```csharp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n方法二：通过反射找出类型的构造函数，然后调用构造函数来获取实例引用。\n\n```csharp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n"
}
