解释反射如何在 .NET 框架中工作

AC# 程序编译为 DLL 程序集,其中包含已编译的 C# 代码以及运行时的元数据和其他资源。C# 提供了一个反射 API,让我们可以在运行时检查元数据和编译后的代码。

使用反射,可以 -

  • 访问程序集中所有类型的程序集元数据

  • 获取类型及其成员(方法、属性等)的列表

  • 在运行时动态调用类型成员。

  • 仅通过提供名称来实例化对象

  • 构建程序集

在传统程序中,当您将源代码编译为机器代码时,编译器会删除有关代码的所有元数据。但是,由于 C# 是一种在公共语言运行时 (CLR) 中运行的托管语言,因此编译器会保留有关代码的大部分信息。反射允许我们检查程序集中的元数据。

该System.Reflection命名空间包含的所有类和其他类型的反射必需的。您还可以通过 System.Reflection.Emit 命名空间中的类型创建新的元数据并以中间语言 (IL) 发出可执行代码。

System.Type使您可以访问类型的元数据。该对象还包括用于枚举类型实例成员的方法,您可以调用这些方法。

using System;
using System.Text;
using System.Reflection;

var sb = new StringBuilder();

// 在运行时键入
Type t1 = sb.GetType();
Console.WriteLine(t1.FullName); // System.Text.StringBuilder

// 编译时输入
Type t2 = typeof (StringBuilder);
Console.WriteLine(t2.FullName); // System.Text.StringBuilder

给定对程序集的引用,也可以按名称获取类型。下面的示例使用当前程序集并获取在 Models 命名空间中定义的 Person 类的类型。

Type personType = Assembly.GetExecutingAssembly().GetType("CSharp.Models.Person");
Console.WriteLine(personType.FullName); // CSharp.Models.Person

Type 类有一些有用的属性,您可以使用它们来访问类型的名称、程序集、可见性、基类型等。

using System;
using System.Text;
using System.Reflection;
var sb = new StringBuilder();
// 在运行时键入
Type t1 = sb.GetType();
// What's the type's name?
Console.WriteLine(t1.FullName); // System.Text.StringBuilder
// What's the type's base type?
Console.WriteLine(t1.BaseType); // System.Object
// Which assembly is the type defined in?
Console.WriteLine(t1.Assembly); // System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
// Is the type public?
Console.WriteLine(t1.IsPublic); // True

随着这些特性,还有诸如方法GetProperties(),GetMethods()以及GetFields()提供访问类型的成员。重要的是获得对类型的 Type 对象的引用。有两种方法可以实现这一点 -

object.GetType():

所有类型都包含此功能。它在运行时返回类型

类型(类):

此表达式在编译时获取类型。它在编译时绑定到特定的 Type 实例,并直接将类型作为参数。

System.Reflection命名空间中的类以及命名空间中定义的类System.Type允许您获取有关程序集及其中类型的信息,例如类、接口和值类型。