# C# 反射(Reflection)
动态获取类型信息,动态创建对象,动态访问成员的过程。
# 优缺点
优点:
- 反射提高了程序的灵活性和扩展性。
- 降低耦合性,提高自适应能力。
- 它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
缺点:
- 性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
- 使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。
# 反射的用途
- 它允许在运行时查看特性(attribute)信息。
- 它允许审查集合中的各种类型,以及实例化这些类型。
- 它允许延迟绑定的方法和属性(property)。
- 它允许在运行时创建新类型,然后使用这些类型执行一些任务。
# 使用流程
- 获取数据类型
- 动态创建对象
- 访问数据成员
# 创建一个类作为例子
public class User | |
{ | |
public int ID { get; set; } | |
public string Name { get; set; } | |
public void Print() | |
{ | |
Console.WriteLine("Name:" + Name + "\tId:" + ID); | |
} | |
} |
# 获取数据类型
有三种方法
//Type(User,int,string 是数据类型 Type 是类型) | |
Type type = Type.GetType("Day05_Reflex.User"); // 命名空间。类名(这种方式性能最差) | |
Type type = user_0.GetType(); | |
Type type = typeof(User); |
# 动态创建对象
// 利用类型创建 | |
object object_type = Activator.CreateInstance(type); | |
// 利用程序集和类名创建 | |
object object = Assembly.Load("Day05_Reflex").CreateInstance("User"); |
# 访问数据成员
PropertyInfo propertyInfo_ID = type.GetProperty("ID"); // 获取属性 | |
object IDValue = Convert.ChangeType("1001", propertyInfo_ID.PropertyType); // 类型转换 | |
propertyInfo_ID.SetValue(object_type, IDValue); // 设置属性 | |
//string 类型不需要做类型转换 | |
PropertyInfo propertyInfo_Name = type.GetProperty("Name"); // 获取属性 | |
propertyInfo_Name.SetValue(object_type, "Test"); // 设置属性 | |
MethodInfo methodInfo_0 = type.GetMethod("Print"); // 获取方法 | |
methodInfo_0.Invoke(object_type, null); // 调用方法 |
# 例子:JSON 解析
JSON 解析是一个很好的例子,具体代码请看这篇文章