コード例 #1
0
        /// <summary>
        /// 创建指定 <paramref name="constructorInfo"/> 的动态构造函数。
        /// </summary>
        /// <param name="constructorInfo">构造函数的元数据。</param>
        /// <returns>绑定到实例构造函数的委托。</returns>
        public static DynamicConstructorHandler CreateConstructorHandler(this ConstructorInfo constructorInfo)
        {
            if (constructorInfo == null)
            {
                throw new ArgumentNullException(nameof(constructorInfo));
            }
            return(ConstructorCache.GetOrAdd(constructorInfo, m =>
            {
                var declaringType = m.DeclaringType;

                var emit = new EmitHelper(DefineTypes.Object, new Type[] { DefineTypes.ObjectArray }, declaringType);

                var parameterInfos = m.GetParameters();
                var parameterLength = parameterInfos.Length;
                var parameterLocals = new LocalBuilder[parameterLength];
                var hasByRef = false;

                CreateParameterLocals(0, emit, parameterInfos, parameterLength, parameterLocals, ref hasByRef);
                LoadParameterLocals(emit, parameterInfos, parameterLength, parameterLocals);

                emit.newobj(m)
                .boxIfValueType(declaringType)
                .end();

                if (hasByRef)
                {
                    SaveParameters(0, emit, parameterInfos, parameterLength, parameterLocals);
                }

                emit.ret().end();
                return emit.CreateDelegate <DynamicConstructorHandler>();
            }));
        }
コード例 #2
0
        /// <summary>
        /// 创建方法的调用委托。
        /// </summary>
        /// <param name="methodInfo">方法元数据。方法不能是一个尚未构造泛型参数的方法</param>
        /// <returns>方法调用的委托。</returns>
        public static DynamicMethodInvoker CreateMethodInvoker(this MethodInfo methodInfo)
        {
            if (methodInfo == null)
            {
                throw new ArgumentNullException(nameof(methodInfo));
            }
            if (methodInfo.IsGenericMethodDefinition)
            {
                throw new ArgumentException("不支持尚未构造泛型参数的方法。", nameof(methodInfo));
            }

            return(MethodCache.GetOrAdd(methodInfo, m =>
            {
                var declaringType = m.DeclaringType;

                var emit = new EmitHelper(DefineTypes.Object, new Type[] { DefineTypes.Object, DefineTypes.ObjectArray }, declaringType);
                var isStatic = m.IsStatic;
                var returnType = m.ReturnType;           //- 方法的返回类型
                var parameterInfos = m.GetParameters();  //- 方法的参数集合
                var parameterLength = parameterInfos.Length;
                var parameterLocals = new LocalBuilder[parameterLength];
                var hasByRef = false;

                CreateParameterLocals(1, emit, parameterInfos, parameterLength, parameterLocals, ref hasByRef);

                if (!isStatic)
                {
                    emit.ldarg_0
                    .castType_any(declaringType)
                    .end();
                }

                LoadParameterLocals(emit, parameterInfos, parameterLength, parameterLocals);

                emit.call(isStatic, m);

                if (returnType == typeof(void))
                {
                    emit.ldnull
                    .end();
                }
                else
                {
                    emit.boxIfValueType(returnType)
                    .end();
                }

                if (hasByRef)
                {
                    SaveParameters(1, emit, parameterInfos, parameterLength, parameterLocals);
                }

                emit.ret().end();

                return emit.CreateDelegate <DynamicMethodInvoker>();
            }));
        }