# C# 反射(Reflection)

动态获取类型信息,动态创建对象,动态访问成员的过程。

# 优缺点

优点:

  1. 反射提高了程序的灵活性和扩展性。
  2. 降低耦合性,提高自适应能力。
  3. 它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

缺点:

  1. 性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
  2. 使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

# 反射的用途

  • 它允许在运行时查看特性(attribute)信息。
  • 它允许审查集合中的各种类型,以及实例化这些类型。
  • 它允许延迟绑定的方法和属性(property)。
  • 它允许在运行时创建新类型,然后使用这些类型执行一些任务。

# 使用流程

  1. 获取数据类型
  2. 动态创建对象
  3. 访问数据成员

# 创建一个类作为例子

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 解析是一个很好的例子,具体代码请看这篇文章