protected internal override Delegate CreateDelegate()
        {
            /*
             * Type elementType = TargetType.GetElementType();
             * Generator
             *      .ldarg_0                       // load array
             *      .castclass(TargetType)         // (T[])array
             *      .ldarg_1                       // load index
             *      .ldarg_2                       // load value
             *      .CastFromObject(elementType)   // (unbox | cast) value
             *      .stelem(elementType)           // array[index] = value
             *      .ret();
             * return Method.CreateDelegate(typeof(ArrayElementSetter));
             */

            Type elementType = TargetType.GetElementType();

            Gen.Emit(OpCodes.Ldarg_0);
            Gen.Emit(OpCodes.Castclass, TargetType);
            Gen.Emit(OpCodes.Ldarg_1);
            Gen.Emit(OpCodes.Ldarg_2);
            if (elementType == typeof(object))
            {
                Gen.Emit(elementType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, elementType);
            }
            Gen.Emit(OpCodes.Stelem, elementType);
            Gen.Emit(OpCodes.Ret);
            return(Method.CreateDelegate(typeof(ArrayElementSetter)));
        }
        protected internal override Delegate CreateDelegate()
        {
            Type elementType = TargetType.GetElementType();

            Gen.Emit(OpCodes.Ldarg_0);
            Gen.Emit(OpCodes.Castclass, TargetType);
            Gen.Emit(OpCodes.Ldarg_1);
            Gen.Emit(OpCodes.Ldelem, elementType);
            if (TargetType.IsValueType)
            {
                Gen.Emit(OpCodes.Box, TargetType);
            }
            Gen.Emit(OpCodes.Ret);
            return(Method.CreateDelegate(typeof(ArrayElementGetter)));
        }
        protected internal override Delegate CreateDelegate()
        {
            if (ReflectionUtils.IsTargetTypeStruct(TargetType) && ReflectionUtils.IsEmptyTypeList(ParameterTypes))
            {
                // No-arg struct needs special initialization
                Emit.DeclareLocal(TargetType);                      // TargetType tmp
                Emit.ldloca_s(0)                                    // &tmp
                .initobj(TargetType)                                // init_obj(&tmp)
                .ldloc_0.end();                                     // load tmp
            }
            else if (TargetType.IsArray)
            {
                Emit.ldarg_0                                                  // load args[] (method arguments)
                .ldc_i4_0                                                     // load 0
                .ldelem_ref                                                   // load args[0] (length)
                .unbox_any(typeof(int))                                       // unbox stack
                .newarr(TargetType.GetElementType());                         // new T[args[0]]
            }
            else
            {
                ConstructorInfo ctorInfo = TargetType.GetConstructor(Flags, null, ParameterTypes, null);
                byte            startUsableLocalIndex = 0;
                if (ReflectionUtils.HasRefParam(ParameterTypes))
                {
                    startUsableLocalIndex = CreateLocalsForByRefParams(0, ctorInfo);      // create by_ref_locals from argument array
                    Emit.DeclareLocal(TargetType);                                        // TargetType tmp;
                }

                PushParamsOrLocalsToStack(0);                               // push arguments and by_ref_locals
                Emit.newobj(ctorInfo);                                      // ctor (<stack>)

                if (ReflectionUtils.HasRefParam(ParameterTypes))
                {
                    Emit.stloc(startUsableLocalIndex);                          // tmp = <stack>;
                    AssignByRefParamsToArray(0);                                // store by_ref_locals back to argument array
                    Emit.ldloc(startUsableLocalIndex);                          // tmp
                }
            }
            Emit.boxIfValueType(TargetType)
            .ret();                                                    // return (box)<stack>;
            return(Method.CreateDelegate(typeof(ConstructorInvoker)));
        }
 protected internal override Delegate CreateDelegate()
 {
     if (IsTargetTypeStruct && HasNoParam)          // no-arg struct needs special initialization
     {
         Gen.DeclareLocal(TargetType);              // TargetType tmp
         Gen.Emit(OpCodes.Ldloca_S, (byte)0);       // &tmp
         Gen.Emit(OpCodes.Initobj, TargetType);     // init_obj(&tmp)
         Gen.Emit(OpCodes.Ldloc_0);                 // load tmp
     }
     else if (TargetType.IsArray)
     {
         Gen.Emit(OpCodes.Ldarg_0);                             // load args[] (method arguments)
         Gen.Emit(OpCodes.Ldc_I4_0);                            // load 0
         Gen.Emit(OpCodes.Ldelem_Ref);                          // load args[0] (length)
         Gen.Emit(OpCodes.Unbox_Any, typeof(int));              // unbox stack
         Gen.Emit(OpCodes.Newarr, TargetType.GetElementType()); // new T[args[0]]
     }
     else
     {
         ConstructorInfo ctorInfo = (ConstructorInfo)MemberInfo;
         byte            startUsableLocalIndex = 0;
         if (HasRefParam)
         {
             startUsableLocalIndex = CreateLocalsForByRefParams(0, ctorInfo); // create by_ref_locals from argument array
             Gen.DeclareLocal(TargetType);                                    // TargetType tmp;
         }
         PushParamsOrLocalsToStack(0);                                        // push arguments and by_ref_locals
         Gen.Emit(OpCodes.Newobj, ctorInfo);                                  // ctor (<stack>)
         if (HasRefParam)
         {
             stloc_s(startUsableLocalIndex);                        // tmp = <stack>;
             AssignByRefParamsToArray(0);                           // store by_ref_locals back to argument array
             Gen.Emit(OpCodes.Ldloc, (short)startUsableLocalIndex); // tmp
         }
     }
     if (TargetType.IsValueType)
     {
         Gen.Emit(OpCodes.Box, TargetType);
     }
     Gen.Emit(OpCodes.Ret);             // return (box)<stack>;
     return(Method.CreateDelegate(typeof(ConstructorInvoker)));
 }