反射允许在运行时分析程序集(如DLL或EXE文件)中的类型信息,并基于这些信息动态地创建对象、调用方法、访问字段和属性等。
举个C#反射简单的栗子:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public void SayHello()
{
Console.WriteLine($"{FirstName}{LastName}");
}
}
然后,可以用反射来动态地创建Person
对象、获取其属性和方法,并执行方法:
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
// 获取Person类的类型信息
Type personType = typeof(Person);
// 使用反射创建Person类的实例,
// Activator.CreateInstance 是 .NET Framework 和 .NET Core 提供的一个静态方法
// 属于System命名空间下的Activator类,主要功能是在运行时动态地创建指定类型的实例。
// 调用CreateInstance方法,在内存中创建一个新的Person类型的对象
// 这一行代码的目的是在不知道具体类型的情况下
// 根据类型信息在运行时创建Person类的一个实例
// 并将其赋值给Person类型的变量personInstance。
Person personInstance = (Person)Activator.CreateInstance(personType);
// 获取FirstName属性并设置值
PropertyInfo firstNameProperty = personType.GetProperty("FirstName");
firstNameProperty.SetValue(personInstance, "山本");
// 获取LastName属性并设置值
PropertyInfo lastNameProperty = personType.GetProperty("LastName");
lastNameProperty.SetValue(personInstance, "仙人");
// 获取SayHello方法并执行
MethodInfo sayHelloMethod = personType.GetMethod("SayHello");
sayHelloMethod.Invoke(personInstance, null); // 调用无参数的方法
// 输出:
// 山本仙人
}
}
这个例子并没有直接通过类名去new一个Person
对象,而是通过反射获取了Person
类的类型信息,然后利用这些信息动态地设置了属性值,并调用了方法(感兴趣可以搜索其中用到的方法的功能)。这个例子就是C#反射的一个基本应用。
反射可以用来处理未知类型的对象,这对于动态加载组件、实现依赖注入、构建灵活的应用架构等场景非常有用。
但是要注意,频繁或非必要的反射操作,会增加额外的性能开销。