【转载】反射之实例创建ConstructorInfo.Invoke 对比 Activator.CreateInstance
2013-05-14 10:24
441 查看
About a year ago I blogged about different methods of object instantiation and that compiled lambda expressions should be preferred in case same type is instantiated frequently and instantiation performance is critical. However, on many occasions dealing with expression compilation is not worth it, and creating an instance using reflection is simple and usually good enough. Then Activator.CreateInstance seems to be a default choice for such operations. What can be simpler than this call?
?
The problem with this approach is its false sense of simplicity: it gives an impression that the instance will be created without any additional information, for example initialization parameters.
To prove how misleading such simplicity can be you just need to try creating an instance of a string:
?
The line above causes MissingMethodException with message “No parameterless constructor defined for this object”. And of course, System.String does not have a default constructor.
So what to do? We can of course say that if a class does not have default constructor, then instantiating it in such way is a bad idea, and those classes are just not intended to be used with code trying to create class instances in such manner. However, I bet that more often than not the semantics behind the code “Activator.CreateInstance<T>” is “give me some instance of T, I don’t care about how you create it”. Under such conditions invoking an arbitrary class constructor is preferred over dealing with MissingMethodException. So why not using ConstructorInfo.Invoke then?
Of course, once you settle for ConstructorInfo, you have to decide what constructor overload to use. But this is not really different from choosing parameterless overload of Activator.CreateInstance. In many cases you don’t choose default constructor because this the state of the object you need – you choose it because you don’t care about the state and thus would like to run the simplest form of creation. Applying the same logic to classes without default constructor we can choose a constructor overload with fewest number of parameters:
?
One area when this approach can be useful is if there is a need to create an instance of an anonymous type (I know it’s a very special need – why on earth will you want to create an instance of an anonymous type? – but I’ve come across a situation):
?
Anonymous types don’t get a parameterless constructor, but there is a constructor with a number of arguments equal to the number of type’s properties. I would however use syntax GetConstructors().OrderBy(c => c.GetParameters().Length).FirstOrDefault() that can be applied in general case.
?
To prove how misleading such simplicity can be you just need to try creating an instance of a string:
?
So what to do? We can of course say that if a class does not have default constructor, then instantiating it in such way is a bad idea, and those classes are just not intended to be used with code trying to create class instances in such manner. However, I bet that more often than not the semantics behind the code “Activator.CreateInstance<T>” is “give me some instance of T, I don’t care about how you create it”. Under such conditions invoking an arbitrary class constructor is preferred over dealing with MissingMethodException. So why not using ConstructorInfo.Invoke then?
Of course, once you settle for ConstructorInfo, you have to decide what constructor overload to use. But this is not really different from choosing parameterless overload of Activator.CreateInstance. In many cases you don’t choose default constructor because this the state of the object you need – you choose it because you don’t care about the state and thus would like to run the simplest form of creation. Applying the same logic to classes without default constructor we can choose a constructor overload with fewest number of parameters:
?
?
相关文章推荐
- [转载内容]动态创建菜单,menustrip,根据权限显示菜单,控制菜单可用,反射,给窗体传值,反射对象传值,public static Object CreateInstance ( Type type, params Object[] args )
- C# Activator.CreateInstance 动态创建类的实例(一)
- C# Activator.CreateInstance 动态创建类的实例(二)
- .Net的反射中Assembly.CreateInstance()与Activator.CreateInstance()方法的区别
- 抽象工厂模式:简单工厂模式、工厂方法模式对比;在工厂方法模式中使用反射创建对象实例
- 再谈Activator.CreateInstance(Type type)方法创建对象和Expression Tree创建对象性能的比较(更新版)
- Activator.CreateInstance(Type type)方法创建对象和Expression Tree创建对象性能的比较(终结版)
- 关于反射中Assembly.CreateInstance()与Activator.CreateInstance()方法的区别
- 关于反射中Assembly.Load("程序集").CreateInstance("命名空间.类")与Activator.CreateInstance()方法
- 关于反射中Assembly.CreateInstance()与Activator.CreateInstance()方法
- 动态创建菜单,menustrip,根据权限显示菜单,控制菜单可用,反射,给窗体传值,反射对象传值,public static Object CreateInstance ( Type type, params Object[] args )
- [转载].Net 中的反射(动态创建类型实例) - Part.4
- [转载]使用反射技术动态创建类对象(实例代码)
- 构造函数带有参数的情况.反射.用Activator.CreateInstance代替new实现类的实例化
- Activator.CreateInstance 方法创建对象和Expression Tree创建对象性能的比较(构造函数含多参数的情况)
- [反射]利用Activator.CreateInstance(type)实例化表单
- [反射]利用Activator.CreateInstance(type)实例化表单
- .Net 中的反射(动态创建类型实例) - Part.4 - (转载)
- 使用工厂模式创建项目时Assembly.Load(path).CreateInstance(CacheKey)反射错误的问题
- .Net 中的反射(动态创建类型实例) - Part.4(转载)