获取Type的默认构造函数的最有效方法

时间:2008-09-26 22:28:08

标签: c# .net reflection

获取System.Type的默认构造函数(即没有参数的实例构造函数)的最有效方法是什么?

我正在考虑下面的代码,但似乎应该有一种更简单,更有效的方法。

Type type = typeof(FooBar)
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
type.GetConstructors(flags)
    .Where(constructor => constructor.GetParameters().Length == 0)
    .First();

5 个答案:

答案 0 :(得分:124)

type.GetConstructor(Type.EmptyTypes)

答案 1 :(得分:29)

如果您确实需要 ConstructorInfo对象,请参阅Curt Hagenlocher's answer

另一方面,如果你真的只是想在System.Type的运行时创建一个对象,请参阅System.Activator.CreateInstance - 它不仅仅是面向未来的(Activator处理更多细节)比ConstructorInfo.Invoke),它还 更难看。

答案 2 :(得分:2)

如果您有通用类型参数,那么Jeff Bridgman的答案是最好的。 如果你只有一个Type对象代表你想要构建的类型,你可以像Alex Lyman建议的那样使用Activator.CreateInstance(Type),但我被告知它很慢(我个人虽然没有对它进行过分析)。

但是,如果您发现自己经常构建这些对象,那么使用动态编译的Linq表达式有一种更有说服力的方法:

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();
    }
}

只需致电委托给你。您应该缓存此委托,因为不断重新编译Linq表达式可能很昂贵,但如果您缓存委托并每次重用它,它可以非常快!我个人使用按类型索引的静态查找字典。当您处理序列化对象时,此函数会派上用场,您可能只知道类型信息。

  

注意:如果类型不可构造或没有默认构造函数,则可能会失败!

答案 3 :(得分:0)

如果您只想获取默认构造函数来实例化类,并将类型作为函数的泛型类型参数获取,则可以执行以下操作:

T NewItUp<T>() where T : new()
{
   return new T();
}

答案 4 :(得分:-1)

你想尝试FormatterServices.GetUninitializedObject(Type) 这个比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

然而,如果对象具有参数化构造函数

,则此失败

希望这有帮助