-
反射基础概念
- 反射是指在运行时动态地获取程序集、模块、类型、成员(方法、属性、字段等)的相关信息,并且能够在运行时动态地调用类型的成员或创建类型的实例。在C#中,
System.Reflection
命名空间提供了进行反射操作的各种类和接口。
- 反射是指在运行时动态地获取程序集、模块、类型、成员(方法、属性、字段等)的相关信息,并且能够在运行时动态地调用类型的成员或创建类型的实例。在C#中,
-
获取类型信息
- 获取当前程序集中的类型
- 可以使用
Assembly.GetExecutingAssembly
方法获取当前正在执行的程序集,然后通过GetTypes
方法获取程序集中包含的所有类型。例如:
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}"); } } }
- 在这个示例中,
GetExecutingAssembly
获取了当前程序集,GetTypes
返回一个包含程序集中所有类型的数组,然后通过循环打印出每个类型的名称。
- 可以使用
- 通过类型名称获取类型
- 如果知道类型的名称,可以使用
Type.GetType
方法来获取类型。例如:
using System; using System.Reflection; class Program { static void Main() { // 获取System.String类型 Type stringType = Type.GetType("System.String"); Console.WriteLine($"类型名称: {stringType.Name}"); } }
- 这里
Type.GetType
方法的参数是类型的完全限定名。需要注意的是,对于简单类型,如int
(实际上是System.Int32
),要使用完整的名称;对于自定义类型,要包含命名空间和类型名。
- 如果知道类型的名称,可以使用
- 获取当前程序集中的类型
-
获取类型成员信息
- 获取方法信息
- 对于已经获取的类型,可以使用
Type.GetMethods
方法获取该类型的所有公共方法。例如:
using System; using System.Reflection; class MyClass { public void MyMethod() { Console.WriteLine("这是MyMethod方法"); } } class Program { static void Main() { Type myClassType = typeof(MyClass); MethodInfo[] methods = myClassType.GetMethods(); foreach (MethodInfo method in methods) { Console.WriteLine($"方法名称: {method.Name}"); } } }
- 在这个示例中,
GetMethods
返回一个MethodInfo
数组,其中包含了MyClass
类型的所有公共方法的信息。可以通过MethodInfo
对象获取方法的参数类型、返回类型等更多详细信息。
- 对于已经获取的类型,可以使用
- 获取属性信息
- 使用
Type.GetProperties
方法来获取类型的属性信息。例如:
using System; using System.Reflection; class MyClass { public int MyProperty { get; set; } } class Program { static void Main() { Type myClassType = typeof(MyClass); PropertyInfo[] properties = myClassType.GetProperties(); foreach (PropertyInfo property in properties) { Console.WriteLine($"属性名称: {property.Name}"); } } }
- 这里
GetProperties
返回一个PropertyInfo
数组,包含了MyClass
类型的所有公共属性的信息。通过PropertyInfo
对象可以获取属性的类型、是否可读、是否可写等信息。
- 使用
- 获取字段信息
- 要获取类型的字段信息,可以使用
Type.GetFields
方法。例如:
using System; using System.Reflection; class MyClass { public int MyField; } class Program { static void Main() { Type myClassType = typeof(MyClass); FieldInfo[] fields = myClassType.GetFields(); foreach (FieldInfo field in fields) { Console.WriteLine($"字段名称: {field.Name}"); } } }
GetFields
方法返回一个FieldInfo
数组,其中包含了MyClass
类型的所有公共字段的信息。可以通过FieldInfo
对象获取字段的类型等信息。
- 要获取类型的字段信息,可以使用
- 获取方法信息
-
动态创建类型实例
- 可以使用
Activator.CreateInstance
方法来动态创建类型的实例。例如:
using System; using System.Reflection; class MyClass { public MyClass() { Console.WriteLine("这是MyClass的构造函数"); } } class Program { static void Main() { Type myClassType = typeof(MyClass); object instance = Activator.CreateInstance(myClassType); } }
- 在这个示例中,首先获取了
MyClass
的类型对象,然后使用Activator.CreateInstance
方法创建了一个MyClass
的实例。如果类型有带参数的构造函数,CreateInstance
方法也有相应的重载形式来传递参数。
- 可以使用
-
动态调用类型成员
- 动态调用方法
- 对于已经获取的
MethodInfo
对象,可以使用Invoke
方法来动态调用方法。例如:
using System; using System.Reflection; class MyClass { public void MyMethod(int param) { Console.WriteLine($"这是MyMethod方法,参数为 {param}"); } } class Program { static void Main() { Type myClassType = typeof(MyClass); object instance = Activator.CreateInstance(myClassType); MethodInfo method = myClassType.GetMethod("MyMethod"); object[] parameters = new object[] { 10 }; method.Invoke(instance, parameters); } }
- 在这个示例中,首先创建了
MyClass
的实例,然后获取了MyMethod
的MethodInfo
对象,准备好参数数组,最后通过Invoke
方法动态调用MyMethod
,传递实例和参数。
- 对于已经获取的
- 动态访问属性
- 对于属性,可以通过
PropertyInfo
对象的GetValue
和SetValue
方法来动态访问属性的值。例如:
using System; using System.Reflection; class MyClass { public int MyProperty { get; set; } } class Program { static void Main() { Type myClassType = typeof(MyClass); object instance = Activator.CreateInstance(myClassType); PropertyInfo property = myClassType.GetProperty("MyProperty"); // 设置属性值 property.SetValue(instance, 20); // 获取属性值 object value = property.GetValue(instance); Console.WriteLine($"属性值为: {value}"); } }
- 这里先获取了属性的
PropertyInfo
对象,然后通过SetValue
设置属性值,再通过GetValue
获取属性值并输出。
- 对于属性,可以通过
- 动态访问字段
- 对于字段,可以使用
FieldInfo
对象的GetValue
和SetValue
方法来动态访问。例如:
using System; using System.Reflection; class MyClass { public int MyField; } class Program { static void Main() { Type myClassType = typeof(MyClass); object instance = Activator.CreateInstance(myClassType); FieldInfo field = myClassType.GetField("MyField"); // 设置字段值 field.SetValue(instance, 30); // 获取字段值 object value = field.GetValue(instance); Console.WriteLine($"字段值为: {value}"); } }
- 先获取
FieldInfo
对象,然后通过SetValue
和GetValue
方法来设置和获取字段的值。
- 对于字段,可以使用
- 动态调用方法