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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/142356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 15:17:32  来源:igfitidea点击:

Most efficient way to get default constructor of a Type

提问by Wes Haggard

What is the most efficient way to get the default constructor (i.e. instance constructor with no parameters) of a System.Type?

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

I was thinking something along the lines of the code below but it seems like there should be a simplier more efficient way to do it.

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

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

采纳答案by Curt Hagenlocher

type.GetConstructor(Type.EmptyTypes)

回答by Alex Lyman

If you actually needthe ConstructorInfo object, then see Curt Hagenlocher's answer.

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

On the other hand, if you're really just trying to create an object at run-time from a System.Type, see System.Activator.CreateInstance-- it's not just future-proofed (Activator handles more details than ConstructorInfo.Invoke), it's also muchless ugly.

在另一方面,如果你真的只是想创建从一个运行时的对象System.Type,看System.Activator.CreateInstance-它不只是未来需求(活化处理比更多的细节ConstructorInfo.Invoke),这也是很多丑陋的少。

回答by Mohamed Faramawi

you would want to try FormatterServices.GetUninitializedObject(Type) this one is better than Activator.CreateInstance

你会想尝试 FormatterServices.GetUninitializedObject(Type) 这个比 Activator.CreateInstance 更好

However , this method doesn't call the object constructor , so if you are setting initial values there, this won't work Check MSDN for this thing http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject.aspx

但是,此方法不调用对象构造函数,因此,如果您在那里设置初始值,则此方法无效 检查 MSDN 以了解此内容 http://msdn.microsoft.com/en-us/library/system.runtime .serialization.formatterservices.getuninitializedobject.aspx

there is another way here http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx

这里还有另一种方法 http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx

however this one fails if the object have parametrize constructors

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

Hope this helps

希望这可以帮助

回答by Jeff B

If you only want to get the default constructor to instantiate the class, and are getting the type as a generic type parameter to a function, you can do the following:

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

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

回答by DaFlame

If you have the generic type parameter, then Jeff Bridgman's answer is the best one. If you only have a Type object representing the type you want to construct, you could use Activator.CreateInstance(Type)like Alex Lyman suggested, but I have been told it is slow (I haven't profiled it personally though).

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

However, if you find yourself constructing these objects very frequently, there is a more eloquent approach using dynamically compiled Linq Expressions:

但是,如果您发现自己非常频繁地构造这些对象,那么使用动态编译的 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();
    }
}

Just call the delegate returned to you. You should cache this delegate, because constantly recompiling Linq expressions can be expensive, but if you cache the delegate and reuse it each time, it can be very fast! I personally use a static lookup dictionary indexed by type. This function comes in handy when you are dealing with serialized objects where you may only know the Type information.

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

NOTE: This can fail if the type is not constructable or does not have a default constructor!

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