/// <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>(); })); }
/// <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(); } }