Create delegate from constructor

As phoog points out a constructor doesn't "return" a value; plus you get information about it with ConstructorInfo and not MethodInfo; which means you can't create a delegate around it directly. You have to create code that invokes the constructor and returns the value. For example:

var ctor = type.GetConstructor(Type.EmptyTypes);
if (ctor == null) throw new MissingMethodException("There is no constructor without defined parameters for this object");
DynamicMethod dynamic = new DynamicMethod(string.Empty,
            type,
            Type.EmptyTypes,
            type);
ILGenerator il = dynamic.GetILGenerator();

il.DeclareLocal(type);
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);

var func = (Func<object>)dynamic.CreateDelegate(typeof(Func<object>));

Of course, if you don't know the type at compile time then you can only deal with Object...


Try it:

Dictionary<Type, Delegate> cache = new Dictionary<Type, Delegate>();
public T Create<T>()
{
    if (!cache.TryGetValue(typeof(T), out var d))
        d = cache[typeof(T)]
            = Expression.Lambda<Func<T>>(
                Expression.New(typeof(T)),
                Array.Empty<ParameterExpression>())
            .Compile();
    return ((Func<T>)d)();
}

Reflection is very slow! Speed tests are here (in Russian): https://ru.stackoverflow.com/a/860921/218063


It would not be very useful to have a delegate that points to a constructor, since constructors do not have a return value. The delegate would construct an object but give you no way of retaining a reference to it.

You can of course create delegates that return the newly-constructed object:

Func<object> theDelegate = () => new object();

You could also create a delegate from the Invoke() method of the constructor's ConstructorInfo

For other types of objects:

Func<string> theDelegate = () => new string('w', 3);
Func<SomeClassInMyProject> theDelegate = () => new SomeClassInMyProject();

The last line assumes there's an accessible parameterless constructor.

Update with CreateDelegate()

T CallConstructor<T>() where T : new() { return new T(); }
Delegate MakeTheDelegate(Type t)
{
    MethodInfo generic = //use your favorite technique to get the MethodInfo for the CallConstructor method
    MethodInfo constructed = generic.MakeGenericMethod(t);
    Type delType = typeof(Func<>).MakeGenericType(t);
    return constructed.CreateDelegate(delType);
}