/// <summary> /// 创建指定 <paramref name="fieldInfo"/> 的动态字段获取器。 /// </summary> /// <param name="fieldInfo">字段的元数据。</param> /// <param name="declaringType">声明该成员的类。</param> /// <returns>返回一个绑定到实例字段获取器的委托。</returns> protected override DynamicGetMemberHandler CreateHandler(FieldInfo fieldInfo, Type declaringType) { EmitHelper emit = new EmitHelper(string.Empty, Types.Object, new Type[1] { Types.Object }, declaringType, SkipVisibility, false); if (fieldInfo.IsStatic) { emit.LoadStaticField(fieldInfo); } else { emit.LoadThis(fieldInfo); emit.LoadField(fieldInfo); } emit.TryBox(fieldInfo.FieldType); emit.Return(); /* * F = FieldType * public object <None>(T owner, object value) * { * return owner.Field; //如果 Field 为值类型,则 return (object)owner.Field; // 装箱 * } */ return(emit.CreateDelegate <DynamicGetMemberHandler>()); }
/// <summary> /// 创建指定 <paramref name="propertyInfo"/> 的动态属性获取器。 /// </summary> /// <param name="propertyInfo">属性的元数据。</param> /// <param name="declaringType">声明该成员的类。</param> /// <returns>返回一个绑定到实例属性获取器的委托。</returns> protected override DynamicGetMemberHandler CreateHandler(PropertyInfo propertyInfo, Type declaringType) { var methodInfo = propertyInfo.GetGetMethod(true); EmitHelper emit = new EmitHelper(string.Empty, Types.Object, new Type[1] { Types.Object }, declaringType, SkipVisibility, false);//- 为什么这里不使用 OwnerType 而使用 member.DeclaringType,主要是考虑到泛型:<object> if (!methodInfo.IsStatic) { emit.LoadThis(methodInfo); //- 非静态,取出实例 } emit.Call(methodInfo); emit.TryBox(methodInfo.ReturnType); emit.Return(); return(emit.CreateDelegate <DynamicGetMemberHandler>()); }
/// <summary> /// 创建指定 <paramref name="constructorInfo"/> 的动态构造函数。 /// </summary> /// <param name="constructorInfo">构造函数的元数据。</param> /// <param name="declaringType">声明该成员的类。</param> /// <returns>返回一个绑定到实例构造函数的委托。</returns> protected override DynamicConstructorHandler CreateHandler(ConstructorInfo constructorInfo, Type declaringType) { if (declaringType.IsValueType) { return((parameters) => { return Activator.CreateInstance(declaringType, parameters); }); } ParameterInfo[] parameterInfos = constructorInfo.GetParameters(); int paramterLength = parameterInfos.Length; EmitHelper emit = new EmitHelper(string.Empty, Types.Object, new Type[1] { Types.ObjectArray }, declaringType, SkipVisibility, true); Type[] paramTypes = new Type[paramterLength]; LocalBuilder[] locals = new LocalBuilder[paramterLength]; if (paramterLength > 0) { for (int i = 0; i < paramterLength; i++) { if (parameterInfos[i].ParameterType.IsByRef) { paramTypes[i] = parameterInfos[i].ParameterType.GetElementType(); } else { paramTypes[i] = parameterInfos[i].ParameterType; } locals[i] = emit.DeclareLocal(paramTypes[i]); emit.LoadArgument(0); //- 取出参数0 也就是 object[] emit.LoadConstant(i); //- 指定索引号 —— 0 emit.LoadRefElement(); //- 取出索引元素 object[0] emit.CastTo(paramTypes[i]); //- 类型转换,从 object 到指定参数类型。 emit.StoreLocal(locals[i]); } for (int i = 0; i < paramterLength; i++) { //- 取出所有 method 函数的参数 if (parameterInfos[i].ParameterType.IsByRef) { emit.LoadLocalBySpecific(locals[i]); } else { emit.LoadLocal(locals[i]); } } } emit.NewObject(constructorInfo); emit.Return(); return(emit.CreateDelegate <DynamicConstructorHandler>()); }
/// <summary> /// 创建指定 <paramref name="methodInfo"/> 的动态方法。 /// </summary> /// <param name="methodInfo">方法的元数据。</param> /// <param name="declaringType">声明该成员的类。</param> /// <returns>返回一个绑定到实例方法的委托。</returns> protected override DynamicMethodHandler CreateHandler(MethodInfo methodInfo, Type declaringType) { Type returnType = methodInfo.ReturnType; //- 方法的返回类型 ParameterInfo[] parameterInfos = methodInfo.GetParameters(); //- 方法的参数集合 int paramterLength = parameterInfos.Length; EmitHelper emit = new EmitHelper(string.Empty, Types.Object, new Type[2] { Types.Object, Types.ObjectArray }, declaringType, SkipVisibility, false);//- 为什么这里不使用 OwnerType 而使用 member.DeclaringType,主要是考虑到泛型:<object> Type[] paramTypes = new Type[paramterLength]; LocalBuilder[] locals = new LocalBuilder[paramterLength]; for (int i = 0; i < paramterLength; i++) { if (parameterInfos[i].ParameterType.IsByRef) { paramTypes[i] = parameterInfos[i].ParameterType.GetElementType(); } else { paramTypes[i] = parameterInfos[i].ParameterType; } locals[i] = emit.DeclareLocal(paramTypes[i]); emit.LoadArgument(1); //- 取出参数1 也就是 object[] emit.LoadConstant(i); //- 指定索引号 —— 0 emit.LoadRefElement(); //- 取出索引元素 object[0] emit.CastTo(paramTypes[i]); //- 类型转换,从 object 到指定参数类型。 emit.StoreLocal(locals[i]); } if (!methodInfo.IsStatic) { emit.LoadThis(methodInfo); //- 非静态,取出实例 //emit.CastTo(member.DeclaringType); } for (int i = 0; i < paramterLength; i++) { //- 取出所有 method 函数的参数 if (parameterInfos[i].ParameterType.IsByRef) { emit.LoadLocalBySpecific(locals[i]); } else { emit.LoadLocal(locals[i]); } } emit.Call(methodInfo); if (returnType == typeof(void)) { emit.LoadNull(); } else { emit.TryBox(returnType); } for (int i = 0; i < paramterLength; i++) { if (parameterInfos[i].ParameterType.IsByRef) { emit.LoadArgument(1); //- 取出参数1 也就是 object[] emit.LoadConstant(i); //- 指定索引号 —— 0 emit.LoadLocal(locals[i]); //- 加载指定索引的数组元素 emit.TryBox(locals[i].LocalType); //- 尝试装箱 paramTypes[i] emit.StoreLocalByRef(); //- 赋值给 ref 或 out } } emit.Return(); return(emit.CreateDelegate <DynamicMethodHandler>()); }