/// <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>(); })); }
/// <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>(); })); }
static void CreateParameterLocals(int argsIndex, EmitHelper emit, ParameterInfo[] parameterInfos, int parameterLength, LocalBuilder[] parameterLocals, ref bool hasByRef) { for (int i = 0; i < parameterLength; i++) { var parameterInfo = parameterInfos[i]; var parameterType = parameterInfo.ParameterType; if (parameterType.IsByRef) { parameterType = parameterType.GetElementType(); hasByRef = true; } var local = emit.DeclareLocal(parameterType); parameterLocals[i] = local; emit.ldtoken(parameterType) .call(GetTypeFromHandleMethod) .ldarg(argsIndex) //- 取出参数1 也就是 object[] .ldc_i4_(i) //- 指定索引号 —— n .ldelem_ref //- 取出索引元素 object[n] .call(ChangeTypeMethod) .castType_any(parameterType) .stloc(local) .end(); } }