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

本文关键字:有效 方法 默认 取类型 获取 构造函数 | 更新日期: 2023-09-27 17:47:21

获取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创建一个对象,请参阅System.Activator.CreateInstance - 它不仅仅是面向未来的(Activator处理的细节比ConstructorInfo.Invoke),它也不那么丑陋。

如果你有泛型类型参数,那么 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 表达式的成本可能很高,但如果每次都缓存委托并重用它,它会非常快! 我个人使用按类型索引的静态查找字典。 当您处理可能只知道 Type 信息的序列化对象时,此函数会派上用场。

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

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

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

您可能想尝试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

但是,如果对象具有参数化构造函数,则此对象将失败

希望这有帮助