public static Delegate ConstructorCaller(Type delegateType, ConstructorInfo constructor, Type instanceType) { // arguments checks if (!typeof(Delegate).IsAssignableFrom(delegateType)) { throw new ArgumentException("delegateType does not represents a delegate", nameof(delegateType)); } if (instanceType == null && !instanceType.IsValueType) { throw new ArgumentNullException(nameof(instanceType)); } if (constructor == null && !instanceType.IsValueType) { throw new ArgumentException("constructor is null, but instanceType is not a value type", nameof(instanceType)); } // read delegate info var methodInfo = delegateType.GetMethod("Invoke"); var delegateArgs = methodInfo.GetParameters().Select(x => x.ParameterType).ToArray() ?? Type.EmptyTypes; var retType = methodInfo.ReturnType != typeof(void) ? methodInfo.ReturnType : null; // read constructor info var ctorArgs = constructor?.GetParameters().Select(x => x.ParameterType).ToArray() ?? Type.EmptyTypes; if (delegateArgs.Length != ctorArgs.Length) { throw new Exception("deletage's arguments count does not match constructor's arguments count"); } // var targetType = constructor?.DeclaringType ?? instanceType; DynamicMethod wrapper = new DynamicMethod($"ctor_{targetType.Name}_", retType, delegateArgs, typeof(Dynamic), true); IILGenerator gen = wrapper.GetILGenerator().AsInterface(); if (targetType.IsValueType && ctorArgs.Length == 0) { CreateInitValueType(targetType, gen); } else { List <ILArgBuilder> argBuilders = new List <ILArgBuilder>(); for (int i = 0; i < ctorArgs.Length; i++) { argBuilders.Add(ILMethodBuilder.GetArgBuilder(gen, delegateArgs[i], ctorArgs[i])); } for (int i = 0; i < ctorArgs.Length; i++) { argBuilders[i].Prepare((byte)i); } for (int i = 0; i < ctorArgs.Length; i++) { argBuilders[i].PassArg((byte)i); } gen.Newobj(constructor); for (int i = ctorArgs.Length - 1; i >= 0; i--) { argBuilders[i].Finalize_((byte)i); } } gen.Ret(); return(wrapper.CreateDelegate(delegateType)); }