C# 反射(Reflection)学习笔记

什么是反射?

在 .NET 中,反射是一种机制,能够在运行时获取程序集(Assembly)、类型(Type)、成员变量、方法等信息,并且可以动态地使用这些信息。

反射提供了一种强大而灵活的方式访问和操作程序集中的类型和成员。通过反射,我们可以:

  • 在运行时获取类型的信息并创建该类型的对象;
  • 获取类型的成员变量、方法和属性等信息;
  • 调用类型的方法,对其进行操作。

反射的优缺点

优点

  • 灵活性高:反射提供了一种动态的访问和操作程序集中类型和成员的方式,允许我们在编写代码时不必知道类型和成员的精确信息。
  • 可重用性强:反射可以在不同的程序集中重复使用,从而使得我们的代码更加灵活。
  • 易于扩展:反射可以无限制地扩展,因为它遵循了 .NET 的基础架构。

缺点

  • 性能较低:反射需要在运行时完成类型和成员信息的检查和调用,因此比直接调用代码性能要低一些。
  • 安全性问题:反射允许我们访问和操作程序集中的类型和成员,因此可能会存在安全性问题。

反射的常用场景

动态地创建对象

csharpCopy Code
Type t = typeof(Person); // 获取类型 object obj = Activator.CreateInstance(t); // 创建对象

动态地获取成员信息

csharpCopy Code
Type t = typeof(Person); // 获取类型 FieldInfo fi = t.GetField("Name"); // 获取字段 MethodInfo mi = t.GetMethod("SayHello"); // 获取方法

动态地调用方法

csharpCopy Code
Type t = typeof(Person); // 获取类型 object obj = Activator.CreateInstance(t); // 创建对象 MethodInfo mi = t.GetMethod("SayHello"); // 获取方法 mi.Invoke(obj, null); // 调用方法

实例演示

以获取类型的成员信息为例,假定我们有一个名为 Person 的类:

csharpCopy Code
public class Person { public string Name; private int Age; public void SayHello() { Console.WriteLine("Hello, my name is {0}, age is {1}", Name, Age); } }

我们可以使用反射获取 Person 类型的公共字段和方法,并打印其信息:

csharpCopy Code
using System; using System.Reflection; class Program { static void Main(string[] args) { Type t = typeof(Person); FieldInfo[] fis = t.GetFields(BindingFlags.Public | BindingFlags.Instance); MethodInfo[] mis = t.GetMethods(BindingFlags.Public | BindingFlags.Instance); Console.WriteLine("Fields:"); foreach (FieldInfo fi in fis) { Console.WriteLine(fi.Name); } Console.WriteLine("Methods:"); foreach (MethodInfo mi in mis) { Console.WriteLine(mi.Name); } Console.ReadKey(); } }

输出结果:

Copy Code
Fields: Name Methods: SayHello ToString Equals GetHashCode GetType

可以看到,我们成功地使用反射获取了 Person 类型的公共字段和方法,并打印了其信息。