Search code examples
c#reflectionexpression-trees.net-4.5

Create delegate from constructor


Using reflection, I'm trying to create a delegate from a parameterless constructor like this:

Delegate del = GetMethodInfo( () => System.Activator.CreateInstance( type ) ).CreateDelegate( delType );

static MethodInfo GetMethodInfo( Expression<Func<object>> func )
{
    return ((MethodCallExpression)func.Body).Method;
}

But I get this exception: "Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type." What will work?

Note that CreateDelegate was moved, for this profile at least, since the previous version of .NET. Now it's on MethodInfo.


Solution

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