/* 修改字段 * IL: * void Action(TInstance instance, TField value) { * 1. 载入第一参数: * ldarg.0 * 2. 转换实例类型: (如果需要) * * * 3. 载入第二参数: * ldarg.1 * 4. 转换字段类型: (如果需要) * * * 5. 修改字段: * {OpCode} {FieldTypeName} {TargetTypeName::FieldName} * {OpCode}: * 1). 实例: stfld; * 2). 静态: stsfld; * {FieldTypeName}: * 1). 标量类型: "{TypeName}"; * 2). 引用类型: "class {TypeName}"; * 3). 数值类型: "valuetype {TypeName}"; * * 6. 退出方法 * ret * } */ Delegate InternalFieldSetWithDynamic(FieldInfo member, Type instance, Type value) { var field = member.FieldType; if (value == null) { value = field; } if (!member.IsStatic) { var reflected = member.ReflectedType; if (instance == null) { instance = reflected; } var @dynamic = CreateDynamicMethod(null, new[] { instance, value }, _DynamicOptionsField, member); var il = @dynamic.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); ConvertIfNeeded(il, reflected, instance); // il.Emit(OpCodes.Ldarg_1); ConvertIfNeeded(il, field, value); // il.Emit(OpCodes.Stfld, member); il.Emit(OpCodes.Ret); return(@dynamic.CreateDelegate(TypeMemberSetInstance.MakeGenericType(new[] { instance, value }))); } else { if (instance != null) { throw new ArgumentException(); } var @dynamic = CreateDynamicMethod(null, new[] { value }, _DynamicOptionsField, member); var il = @dynamic.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); ConvertIfNeeded(il, field, value); // il.Emit(OpCodes.Stsfld, member); il.Emit(OpCodes.Ret); return(@dynamic.CreateDelegate(TypeMemberSetStatic.MakeGenericType(new[] { value }))); } }
/* 修改属性 * // IL代码: 实际访问 set_PropertyName() 方法; * * 1. 载入第一参数: * ldarg.0 * 2. 转换实例类型: (如果需要) * * * 3. 载入第二参数: * ldarg.1 * 4. 转换字段类型: (如果需要) * * * 5. 修改字段: * {OpCode} void {TargetTypeName}::set_PropertyName({PropertyTypeName}) * {OpCode}: * 1). 实例: callvirt instance; * 2). 静态: call; * {PropertyTypeName}: * 1). 标量类型: "{TypeName}"; * 2). 引用类型: "class {TypeName}"; * 3). 数值类型: "valuetype {TypeName}"; * * 6. 退出方法 * ret */ Delegate InternalPropertySetWithDynamic(PropertyInfo member, Type instance, Type value) { var method = member.GetSetMethod(true); var property = member.PropertyType; if (value == null) { value = property; } if (!method.IsStatic) { var reflected = method.ReflectedType; if (instance == null) { instance = reflected; } var @dynamic = CreateDynamicMethod(null, new[] { instance, value }, _DynamicOptionsProperty, member); var il = @dynamic.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); ConvertIfNeeded(il, reflected, instance); // il.Emit(OpCodes.Ldarg_1); ConvertIfNeeded(il, property, value); // if (reflected.IsValueType) { il.EmitCall(OpCodes.Call, method, null); } else { il.EmitCall(OpCodes.Callvirt, method, null); } il.Emit(OpCodes.Ret); return(@dynamic.CreateDelegate(TypeMemberSetInstance.MakeGenericType(new[] { instance, value }))); } else { if (instance != null) { throw Error.StaticObjectCannotConvertType("instance"); } var @dynamic = CreateDynamicMethod(null, new[] { value }, _DynamicOptionsProperty, member); var il = @dynamic.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); ConvertIfNeeded(il, property, value); // il.EmitCall(OpCodes.Call, method, null); il.Emit(OpCodes.Ret); return(@dynamic.CreateDelegate(TypeMemberSetStatic.MakeGenericType(new[] { value }))); } }