75

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

我正在按照下面的代码行思考一些事情,但似乎应该有一种更简单更有效的方法来做到这一点。

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

5 回答 5

140
type.GetConstructor(Type.EmptyTypes)
于 2008-09-26T22:30:24.260 回答
31

如果您确实需要ConstructorInfo 对象,请参阅Curt Hagenlocher 的回答

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

于 2008-09-26T23:08:31.640 回答
4

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

但是,如果您发现自己非常频繁地构造这些对象,则使用动态编译的 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 表达式可能会很昂贵,但是如果你缓存委托并每次都重用它,它会非常快!我个人使用按类型索引的静态查找字典。当您处理可能只知道类型信息的序列化对象时,此函数会派上用场。

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

于 2013-07-09T16:04:06.303 回答
2

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

T NewItUp<T>() where T : new()
{
   return new T();
}
于 2013-04-16T19:31:39.080 回答
-2

你会想试试 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

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

希望这可以帮助

于 2008-09-27T00:33:28.533 回答