コード例 #1
0
        /// <summary>
        /// 创建字段的设置器委托。
        /// </summary>
        /// <param name="fieldInfo">字段元数据。</param>
        /// <returns>字段获取器的委托。</returns>
        public static DynamicMemberSetter CreateFieldSetter(this FieldInfo fieldInfo)
        {
            if (fieldInfo == null)
            {
                throw new ArgumentNullException(nameof(fieldInfo));
            }

            return(SetterCache.GetOrAdd(fieldInfo, m =>
            {
                var declaringType = fieldInfo.DeclaringType;

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

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

                emit.ldtoken(fieldInfo.FieldType)
                .call(GetTypeFromHandleMethod)
                .ldarg_1
                .call(ChangeTypeMethod)
                .castType_any(fieldInfo.FieldType)
                .stfld(isStatic, fieldInfo)
                .ret()
                .end();
                return emit.CreateDelegate <DynamicMemberSetter>();
            }));
        }
コード例 #2
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>();
            }));
        }
コード例 #3
0
        /// <summary>
        /// 创建字段的获取器委托。
        /// </summary>
        /// <param name="fieldInfo">字段元数据。</param>
        /// <returns>字段获取器的委托。</returns>
        public static DynamicMemberGetter CreateFieldGetter(this FieldInfo fieldInfo)
        {
            if (fieldInfo == null)
            {
                throw new ArgumentNullException(nameof(fieldInfo));
            }

            return(GetterCache.GetOrAdd(fieldInfo, m =>
            {
                var emit = new EmitHelper(DefineTypes.Object, new Type[] { DefineTypes.Object }, fieldInfo.DeclaringType);
                if (fieldInfo.IsStatic)
                {
                    emit.ldsfld(fieldInfo)
                    .end();
                }
                else
                {
                    emit.ldarg_0
                    .castType(fieldInfo.DeclaringType)
                    .ldfld(fieldInfo)
                    .end();
                }

                emit.boxIfValueType(fieldInfo.FieldType)
                .ret();

                return emit.CreateDelegate <DynamicMemberGetter>();
            }));
        }
コード例 #4
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>();
            }));
        }
コード例 #5
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>();
            }));
        }
コード例 #6
0
        /// <summary>
        /// 创建属性的设置器委托。
        /// </summary>
        /// <param name="propertyInfo">属性元数据。</param>
        /// <returns>属性获取器的委托。</returns>
        public static DynamicMemberSetter CreatePropertySetter(this PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw new ArgumentNullException(nameof(propertyInfo));
            }

            return(SetterCache.GetOrAdd(propertyInfo, m =>
            {
                var declaringType = propertyInfo.DeclaringType;
                var methodInfo = propertyInfo.GetSetMethod(true);
                if (methodInfo == null)
                {
                    return null;
                }

                var emit = new EmitHelper(DefineTypes.Void, new Type[] { DefineTypes.Object, DefineTypes.Object }, declaringType);
                var isStatic = methodInfo.IsStatic;
                if (!isStatic)
                {
                    emit.ldarg_0
                    .castType(declaringType)
                    .end();
                }

                emit.ldtoken(propertyInfo.PropertyType)
                .call(GetTypeFromHandleMethod)
                .ldarg_1
                .call(ChangeTypeMethod)
                .castType_any(propertyInfo.PropertyType)
                .call(isStatic, methodInfo)
                .ret()
                .end();

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