新手关于c#反射的疑问?


今天学到反射,看到如图所示的通过反射创建对象的代码,通过type接收dll文件中指定类的内部信息,然后通过Activator的CreateInstance方法来根据type创建对象,我想问的就是,既然都能拿到内部信息了,那为何不直接拿到这个类,通过new的方式创建对象呢?

阅读 2.1k
1 个回答
为何不直接拿到这个类,通过new的方式创建对象呢

问题在于,怎么直接拿到这个类?如果能直接拿到这个类用于 new 运算符,哪里还需要反射?

从处理时期来说,都是在运行时产生对象,但是 new 运算符会在编译期进行静态检查,CreateInstance() 是在运行时进行动态检查 …… 比如说 type 对应的类没有无参构造函数,但是使用了 CreateInstance(type) 来构造对象,在编译的时候是没问题的,但在运行的时候会抛出异常。


先想像一下,创建对象的过程是什么?

是使用 new 运算符来 构造对象 ——new 运算符实际是调用了类的构造函数(或者叫构造方法)

通过反射,可以拿到一个 Type。但是从这个 Type 没办法简单的构造出对应的对象来,因为这个 Type 虽然描述了你想要的那个类的信息,但编译器并不知道它是什么,只有运行时知道。new 运算符后面接的是一个构造函数(或简单地认为是一个类),在运行时,没有办法使用 new 运算符,从找到的类型描述(Type 对象)构造对象。

如果要动态的构造对象,需要先找到 Type 中描述的构造函数。Type 有三个方法可以拿到构造函数:GetConstructor, GetConstructorsGetConstructorImpl。比较常用的是第一个,找到正确的构造函数之后,会得到一个 ConstructorInfo 对象,在这个对象上调用 Invoke 方法并传入正确的参数,可以创建所需要的实例。

这个过程很清晰,就是代码写起来比较长,而且可能还要加入一些代码来处理容错。

不过既然构造实例是这么复杂的一个过程,而且步骤基本上没啥变化,为啥不写一个工具函数来简化处理呢 —— Activator.CreateInstance(...) 系列方法不就干这个事情的么?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进