Most efficient way to get default constructor of a Type
Asked Answered
O

5

83

What is the most efficient way to get the default constructor (i.e. instance constructor with no parameters) of a 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();
Oler answered 26/9, 2008 at 22:28 Comment(0)
C
151
type.GetConstructor(Type.EmptyTypes)
Cantrell answered 26/9, 2008 at 22:30 Comment(3)
the static members you just never look at... this is awesome.Notional
Private members are not looked at either. Assuming you only need public then this does appear to be the simplest. However is it the fastest? I'm working on a test right now to find out.Oler
After some measuring this approach vs my approach using MeasureIt (msdn.microsoft.com/en-us/magazine/cc500596.aspx) this approach is faster in all but the simplest cases and even then it is barely slower. So this is both the simplest and the fastest. Thanks!Oler
A
33

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

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 much less ugly.

Andrea answered 26/9, 2008 at 23:8 Comment(2)
Potentially dangerous advice, because certain objects don't have default constructors (String being one). So if you just call this willy-nilly, you might end up with a MissingMethod exception. I actually have to check for a default constructor before calling this method.Neuron
As cunningdave writes, you would most probably want to catch and gracefully handle at least a part of the exception set that may be thrown by this method, which would make the call much less beautiful again. The solution with ConstructorInfo on the other hand looks actually kind of ugly first, but allows you to handle all those exceptional cases without to throw and catch exceptions first, which may be a costly thing.Gazelle
C
4

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).

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

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.

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

Conurbation answered 9/7, 2013 at 16:4 Comment(0)
F
3

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();
}
Fathometer answered 16/4, 2013 at 19:31 Comment(0)
S
-2

you would want to try FormatterServices.GetUninitializedObject(Type) this one is better than 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

there is another way here 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

Supralapsarian answered 27/9, 2008 at 0:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.