在 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
命名空间包含以下类:

上图显示了 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
。在这里,我们使用了带有 studentName
的 GetType()
并将其赋值给 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
。
然后,我们使用 t
的 Assembly
属性,即 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* 等)的信息。