protected virtual Func <object[], object> CreateInvoker()
        {
            var dynamicMethod = new DynamicMethod($"invoker-{Guid.NewGuid()}", typeof(object), new Type[] { typeof(object[]) }, _reflectionInfo.Module, true);
            var ilGen         = dynamicMethod.GetILGenerator();

            var parameterTypes = _reflectionInfo.GetParameterTypes();

            if (parameterTypes.Length == 0)
            {
                ilGen.Emit(OpCodes.Newobj, _reflectionInfo);
                return(CreateDelegate());
            }
            var refParameterCount = parameterTypes.Count(x => x.IsByRef);

            if (refParameterCount == 0)
            {
                for (var i = 0; i < parameterTypes.Length; i++)
                {
                    ilGen.EmitLoadArg(0);
                    ilGen.EmitInt(i);
                    ilGen.Emit(OpCodes.Ldelem_Ref);
                    ilGen.EmitConvertFromObject(parameterTypes[i]);
                }
                ilGen.Emit(OpCodes.Newobj, _reflectionInfo);
                return(CreateDelegate());
            }
            var indexedLocals = new IndexedLocalBuilder[refParameterCount];
            var index         = 0;

            for (var i = 0; i < parameterTypes.Length; i++)
            {
                ilGen.EmitLoadArg(0);
                ilGen.EmitInt(i);
                ilGen.Emit(OpCodes.Ldelem_Ref);
                if (parameterTypes[i].IsByRef)
                {
                    var defType      = parameterTypes[i].GetElementType();
                    var indexedLocal = new IndexedLocalBuilder(ilGen.DeclareLocal(defType), i);
                    indexedLocals[index++] = indexedLocal;
                    ilGen.EmitConvertFromObject(defType);
                    ilGen.Emit(OpCodes.Stloc, indexedLocal.LocalBuilder);
                    ilGen.Emit(OpCodes.Ldloca, indexedLocal.LocalBuilder);
                }
                else
                {
                    ilGen.EmitConvertFromObject(parameterTypes[i]);
                }
            }
            ilGen.Emit(OpCodes.Newobj, _reflectionInfo);
            for (var i = 0; i < indexedLocals.Length; i++)
            {
                ilGen.EmitLoadArg(0);
                ilGen.EmitInt(indexedLocals[i].Index);
                ilGen.Emit(OpCodes.Ldloc, indexedLocals[i].LocalBuilder);
                ilGen.EmitConvertToObject(indexedLocals[i].LocalType);
                ilGen.Emit(OpCodes.Stelem_Ref);
            }
            return(CreateDelegate());

            Func <object[], object> CreateDelegate()
            {
                if (_reflectionInfo.DeclaringType.IsValueType)
                {
                    ilGen.EmitConvertToObject(_reflectionInfo.DeclaringType);
                }
                ilGen.Emit(OpCodes.Ret);
                return((Func <object[], object>)dynamicMethod.CreateDelegate(typeof(Func <object[], object>)));
            }
        }
            protected override Func <object, object[], object> CreateInvoker()
            {
                DynamicMethod dynamicMethod = new DynamicMethod($"invoker_{_displayName}",
                                                                typeof(object), new Type[] { typeof(object), typeof(object[]) }, _reflectionInfo.Module, true);

                ILGenerator ilGen          = dynamicMethod.GetILGenerator();
                var         parameterTypes = _reflectionInfo.GetParameterTypes();

                if (parameterTypes.Length == 0)
                {
                    return(CreateDelegate());
                }

                var refParameterCount = parameterTypes.Count(x => x.IsByRef);

                if (refParameterCount == 0)
                {
                    for (var i = 0; i < parameterTypes.Length; i++)
                    {
                        ilGen.EmitLoadArg(1);
                        ilGen.EmitInt(i);
                        ilGen.Emit(OpCodes.Ldelem_Ref);
                        ilGen.EmitConvertFromObject(parameterTypes[i]);
                    }
                    return(CreateDelegate());
                }

                var indexedLocals = new IndexedLocalBuilder[refParameterCount];
                var index         = 0;

                for (var i = 0; i < parameterTypes.Length; i++)
                {
                    ilGen.EmitLoadArg(1);
                    ilGen.EmitInt(i);
                    ilGen.Emit(OpCodes.Ldelem_Ref);
                    if (parameterTypes[i].IsByRef)
                    {
                        var defType      = parameterTypes[i].GetElementType();
                        var indexedLocal = new IndexedLocalBuilder(ilGen.DeclareLocal(defType), i);
                        indexedLocals[index++] = indexedLocal;
                        ilGen.EmitConvertFromObject(defType);
                        ilGen.Emit(OpCodes.Stloc, indexedLocal.LocalBuilder);
                        ilGen.Emit(OpCodes.Ldloca, indexedLocal.LocalBuilder);
                    }
                    else
                    {
                        ilGen.EmitConvertFromObject(parameterTypes[i]);
                    }
                }

                return(CreateDelegate(() =>
                {
                    for (var i = 0; i < indexedLocals.Length; i++)
                    {
                        ilGen.EmitLoadArg(1);
                        ilGen.EmitInt(indexedLocals[i].Index);
                        ilGen.Emit(OpCodes.Ldloc, indexedLocals[i].LocalBuilder);
                        ilGen.EmitConvertToObject(indexedLocals[i].LocalType);
                        ilGen.Emit(OpCodes.Stelem_Ref);
                    }
                }));

                Func <object, object[], object> CreateDelegate(Action callback = null)
                {
                    ilGen.EmitCall(OpCodes.Call, _reflectionInfo, null);
                    callback?.Invoke();
                    if (_reflectionInfo.ReturnType == typeof(void))
                    {
                        ilGen.Emit(OpCodes.Ldnull);
                    }
                    else if (_reflectionInfo.ReturnType.IsValueType)
                    {
                        ilGen.EmitConvertToObject(_reflectionInfo.ReturnType);
                    }
                    ilGen.Emit(OpCodes.Ret);
                    return((Func <object, object[], object>)dynamicMethod.CreateDelegate(typeof(Func <object, object[], object>)));
                }
            }