以下两种创建对象的方法之间是否有任何区别。
Student s1 = Activator.CreateInstance<Student>();
Student s1 = new Student();
答案 0 :(得分:11)
编译器使用“Activator.CreateInstance”方法的这种重载来实现使用泛型实现类型参数指定的类型的实例化。
假设您有以下方法:
public static T Factory<T>() where T: new()
{
return new T();
}
编译器将转换“return new T();”调用“CreateInstance”。
通常,应用程序代码中的CreateInstance没有用处,因为必须在编译时知道该类型。如果在编译时已知类型,则可以使用正常的实例化语法(C#中的new运算符,Visual Basic中的New,C ++中的gcnew)。
答案 1 :(得分:6)
我不会将Activator.CreateInstance()
称为多余的。
如果您知道类型,是的,您只需使用new
。但是,在需要从插件框架动态加载未知类型或者从字符串(例如,设置文件)中解析类型的情况下,它非常有用。
并回答关于两者之间差异的问题,不,在引擎盖下,调用new T()
和Activator.CreateInstance<T>()
之间没有真正的区别,正如Andrew Hare已经指出的那样。
编辑:没关系,我把通用的CreateInstance<T>()
与通常使用的CreateInstance(Type type)
答案 2 :(得分:4)
调用new是性能更好的CreateInstance可能使用缓慢的反射 如果您在设计时知道类型 - 使用new,即使两个调用完全相同(它们不是!)为什么会使代码过于复杂?
仅当您在设计时不知道T的类型并且需要该类型的运行时解析时才使用Activator.CreateInstance。
答案 3 :(得分:3)
不,Activator.CreateInstance<T>
只是调用默认构造函数。您的示例之间的唯一区别是对CreateInstance<T>
的额外方法调用。
来自Activator.CreateInstance<T>
:
创建该类型的实例 由指定的通用指定 类型参数,使用 无参数构造函数。
答案 4 :(得分:3)
一个很大的区别是
Student s1 = new Student();
如果Student
上没有默认构造函数,将无法编译,而
Student s1 = Activator.CreateInstance<Student>();
即使Student
没有默认构造函数,也会编译。 (它将编译,让你运行程序,但如果没有匹配的构造函数,你将得到一个异常,而如果构造函数不存在,构造函数调用甚至不会编译。)
类似地,CreateInstance
调用是对类的隐式使用,因此,例如,Resharper将不知道您正在实例化它,并且可能会告诉您该类从未实例化。
如其他答案中所述,CreateInstance
调用还允许使用泛型类型参数:
T s1 = Activator.CreateInstance<T>();
尽管使用new
类型约束可能会更好,因为它可以让你在编译时确保实际上有一个构造函数被调用。
然而,Activator.CreateInstance(Type, ...)
重载更有用。