原理:反射是指在运行时获取程序集、类型、成员等信息,并能够动态地创建对象、调用方法、访问属性等。C#的反射机制是通过 System.Reflection 命名空间下的类型来实现的,它允许程序在运行时检查和操作自身的元数据。
作用:实现动态编程,在运行时根据条件创建对象、调用方法,提高程序的灵活性和可扩展性。
支持插件式架构,使程序能够在运行时加载外部程序集并使用其中的类型和功能。
用于序列化和反序列化,帮助将对象转换为字节流或从字节流恢复对象。
应用场景:依赖注入框架,如Unity、Autofac等,通过反射来创建对象并注入依赖。
动态加载插件,游戏开发中可在运行时加载不同的游戏模块。
代码分析工具,用于分析程序集的结构和成员信息。
数据绑定,如将数据对象的属性动态绑定到UI控件上。
序列化与反序列化,如JSON、XML序列化库使用反射来处理对象的成员。
代码案例及解析
1. 获取类型信息
csharp
using System;
using System.Reflection;
class Program
{
static void Main()
{
Type type = typeof(int);
Console.WriteLine($"Type Name: {type.Name}");
Console.WriteLine($"Namespace: {type.Namespace}");
}
}
解析:通过 typeof 获取 int 类型的 Type 对象,然后访问其 Name 和 Namespace 属性,输出类型的名称和命名空间。
1. 动态创建对象
csharp
using System;
using System.Reflection;
class MyClass
{
public MyClass()
{
Console.WriteLine("MyClass constructor called.");
}
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
object instance = Activator.CreateInstance(type);
}
}
解析:获取 MyClass 的 Type 对象,使用 Activator.CreateInstance 方法根据类型动态创建 MyClass 的实例,调用了 MyClass 的构造函数。
1. 调用方法
csharp
using System;
using System.Reflection;
class MyClass
{
public void SayHello()
{
Console.WriteLine("Hello!");
}
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("SayHello");
method.Invoke(instance, null);
}
}
解析:先创建 MyClass 的实例,然后通过 Type 获取 SayHello 方法的 MethodInfo ,再使用 Invoke 方法在实例上调用该方法。
1. 访问属性
csharp
using System;
using System.Reflection;
class MyClass
{
public int MyProperty { get; set; }
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
object instance = Activator.CreateInstance(type);
PropertyInfo property = type.GetProperty("MyProperty");
property.SetValue(instance, 42);
int value = (int)property.GetValue(instance);
Console.WriteLine(value);
}
}
解析:创建 MyClass 实例后,获取 MyProperty 属性的 PropertyInfo ,通过 SetValue 设置属性值,再用 GetValue 获取属性值并输出。
1. 遍历程序集的类型
csharp
using System;
using System.Reflection;
class Program
{
static void Main()
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
Console.WriteLine(type.Name);
}
}
}
解析:通过 Assembly.GetExecutingAssembly 获取当前程序集,再使用 GetTypes 方法获取程序集中的所有类型,然后遍历输出类型名称。