获得Type的默认构造函数的最有效的方法
什么是最有效的方式来获取System.Type的默认构造函数(即没有参数的实例构造函数)?
我正在考虑下面的代码,但似乎应该有一个更简单,更有效的方法来做到这一点。
Type type = typeof(FooBar) BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; type.GetConstructors(flags) .Where(constructor => constructor.GetParameters().Length == 0) .First();
type.GetConstructor(Type.EmptyTypes)
如果实际上需要 ConstructorInfo对象,请参阅Curt Hagenlocher的答案 。
另一方面,如果你真的只是试图从System.Type
运行时创build一个对象,请参阅System.Activator.CreateInstance
– 它不仅仅是面向未来的(Activator处理比ConstructorInfo.Invoke
更多的细节) ,它也不那么难看。
如果你有genericstypes参数,那么Jeff Bridgman的答案是最好的。 如果你只有一个Type对象来表示你想要构造的types,你可以像Alex Lyman所build议的那样使用Activator.CreateInstance(Type)
,但是我已经被告知它很慢(我个人还没有对它进行描述)。
但是,如果您发现自己经常构build这些对象,那么使用dynamic编译的Linqexpression式就更有说服力了:
using System; using System.Linq.Expressions; public static class TypeHelper { public static Func<object> CreateDefaultConstructor(Type type) { NewExpression newExp = Expression.New(type); // Create a new lambda expression with the NewExpression as the body. var lambda = Expression.Lambda<Func<object>>(newExp); // Compile our new lambda expression. return lambda.Compile(); } }
只要打电话给委托人。 你应该caching这个委托,因为不断地重新编译Linqexpression式可能是很昂贵的,但是如果你caching委托并且每次重用它,它可以非常快! 我个人使用types索引的静态查找字典。 当你处理序列化的对象时,这个函数会派上用场,你可能只知道types信息。
注意:如果types不可构造或没有默认构造函数,则可能会失败!
如果您只想获取默认的构造函数来实例化类,并将该types作为函数的genericstypes参数获取,则可以执行以下操作:
T NewItUp<T>() where T : new() { return new T(); }
你会想尝试FormatterServices.GetUninitializedObject(types)这一个比Activator.CreateInstance
但是,这种方法不会调用对象的构造函数,所以如果你在那里设置初始值,这将无法工作检查这个东西的MSDN http://msdn.microsoft.com/en-us/library/system.runtime .serialization.formatterservices.getuninitializedobject.aspx
有另一种方法在这里http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx
然而,如果对象具有参数化构造函数,则会失败
希望这可以帮助