Ejemplo n.º 1
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>();
            }));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 创建属性的获取器委托。
        /// </summary>
        /// <param name="propertyInfo">属性元数据。</param>
        /// <returns>属性获取器的委托。</returns>
        public static DynamicMemberGetter CreatePropertyGetter(this PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw new ArgumentNullException(nameof(propertyInfo));
            }

            return(GetterCache.GetOrAdd(propertyInfo, m =>
            {
                var declaringType = propertyInfo.DeclaringType;

                var methodInfo = propertyInfo.GetGetMethod(true);
                if (methodInfo == null)
                {
                    return null;
                }

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

                if (!isStatic)
                {
                    emit.ldarg_0
                    .castType(declaringType)
                    .callvirt(methodInfo)
                    .end();
                }
                else
                {
                    emit.call(methodInfo)
                    .end();
                }

                emit.boxIfValueType(propertyInfo.PropertyType)
                .ret();

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