C# 反射

在 C# 中,反射允许我们在运行时检查和操作类、构造函数、方法和字段。

例如,我们定义了一个名为 Student 的类,如下所示:

class Student
{
    // a field 
    public int age;
    // method 
    public void score()
    {
        // .. some code
    }
}

上面的 Student 类包含一个字段和一个方法。借助反射,我们可以在运行时检查这些信息。

我们将在下面详细介绍反射。


什么是 C# 反射?

在 C# 中,有一个称为 **程序集 (Assembly)** 的块,它由编译器在代码成功编译后自动生成。它包含两个部分:中间语言和元数据。

当我们编写 C# 代码时,它不会直接编译成机器级语言。它首先被编译成一种中间语言,然后打包成 **程序集**。

类似地,元数据包含有关类型(如类、方法、构造函数等)的信息。例如,一个 Student 类包含一些方法和字段。所有这些关于 Student 类的信息都以元数据的形式存在。

反射就是简单地获取这些元数据并检查其中的信息。


C# 反射层次结构

C# 提供了 System.Reflection 命名空间,我们可以使用它来执行反射。System.Reflection 命名空间包含以下类:

classes used to perform reflection
C# 反射层次结构

上图显示了 System.Reflection 命名空间下的一些类。在这些类中,我们将使用 Type 类来演示反射。


C# Type 类

访问元数据的主要方法是使用 Type 类。此类提供了方法和属性,我们可以使用它们来获取有关类型声明的信息。例如:

using System;
using System.Reflection;
public class Program { public static void Main() { String studentName = "Jack";
// get the current type of studentName Type studentNameType = studentName.GetType();
Console.WriteLine("Type is: " + studentNameType); } }

输出

Type is: System.String

在上面的示例中,我们定义了一个 String 类变量 studentName。请注意代码:

// get the current type of studentName
Type studentNameType = studentName.GetType();

GetType() 方法返回当前数据的 Type。在这里,我们使用了带有 studentNameGetType() 并将其赋值给 Type 变量 studentNameType

GetType() 方法返回 System.String,这是 studentName 的当前类型。


示例 1:C# 反射获取程序集

Type 类提供了一个名为 Assembly 的属性,该属性会生成代码的程序集。例如:

using System;
using System.Reflection;
class Program
{
    static void Main()
    {
        // get typeof the Program class and load it to Type variable t     
        Type t = typeof(Program);

// get Assembly of variable t using the Assembly property Console.WriteLine(t.Assembly);
} }

输出

app, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

在上面的示例中,请注意代码,

// get type of Program and load it to Type variable t     
Type t = typeof(Program);

在这里,我们使用了 typeof 运算符,它返回 Program 类的类型,并将其赋值给 Type 变量 t

然后,我们使用 tAssembly 属性,即 t.Assembly,它返回 Program 类的程序集。


示例 2:C# 反射与 Enumerable

我们可以使用 Type 类的属性来获取有关 Enumerable 类型的信息。例如:

using System;
using System.Reflection;
class Program
{
    static void Main()
    {
        // get typeof Enumerable and load it to Type variable t     
        Type t = typeof(Enumerable);

// the Type class properties return information about the Enumerable Type Console.WriteLine("Name : {0}", t.Name); Console.WriteLine("Namespace : {0}", t.Namespace); Console.WriteLine("Base Type : {0}", t.BaseType);
} }

输出

Name : Enumerable
Namespace : System.Linq
Base Type : System.Object

在上面的示例中,我们使用了 Type 类的属性以及 Enumerable 类型:

  • t.Name - 获取类型的名称
  • t.Namespace - 获取类型的命名空间
  • t.BaseType - 获取基类型或父类型

示例 3:C# 反射与 String

我们也可以使用 Type 类的属性来获取有关 String 类型的信息。例如:

using System;
using System.Reflection;
class Program
{
    static void Main()
    {
        // get typeof String and load it to Type variable t     
        Type t = typeof(String);

// the Type class properties return information about the String Type Console.WriteLine("Name : {0}", t.Name); Console.WriteLine("Namespace : {0}", t.Namespace); Console.WriteLine("Base Type : {0}", t.BaseType);
} }

输出

Name : String
Namespace : System
Base Type : System.Object

注意: 我们可以使用 C# 中的反射获取有关其他类型(如 *class*、*delegate*、*array* 等)的信息。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战