System.Reflection.Emit 向 propertyInfo 添加代码
System.Reflection.Emit adding code to propertyInfo
我是 System.Reflection.Emit 的新手,正在尝试从我的库中删除 nuget PropertChanged.Fody 并构建类似的东西。
所以这就是我得到的。
此方法称为 Update属性,但真正的剂量是覆盖 属性Info,因此如果我的 属性Info 不是虚拟的,则此代码将不起作用。
那么是否可以仅更新我的 属性 信息集而不创建新的 属性 ?
private static void UpdateProperty(PropertyInfo propertyInfo, TypeBuilder typeBuilder,
MethodInfo raisePropertyChangedMethod)
{
// Update the setter of the class, here is the problem im creating new PropertyInfo
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyInfo.Name,
PropertyAttributes.None, propertyInfo.PropertyType, null);
// Create set method
MethodBuilder builder = typeBuilder.DefineMethod("set_" + propertyInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual , null, new Type[] { propertyInfo.PropertyType });
builder.DefineParameter(1, ParameterAttributes.None, "value");
ILGenerator generator = builder.GetILGenerator();
// Add IL code for set method
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Call, propertyInfo.GetSetMethod());
// Call property changed for object
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldstr, propertyInfo.Name);
generator.Emit(OpCodes.Callvirt, raisePropertyChangedMethod);
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(builder);
}
AFAIK 没有官方方法可以在运行时替换方法体(或 属性 setter)(除非它是动态方法)。不过,有很多方法可以做到这一点。参见
- Dynamically replace the contents of a C# method?
- How do I replace a method implementation at runtime?
但是当 属性 值更改时注入引发 PropertyChanged 方法的代码可以在编译时完成(这就是 PropertyChanged.Fody 所做的)并且看起来对我来说,这是比运行时代码修改更可取的解决方案。
我是 System.Reflection.Emit 的新手,正在尝试从我的库中删除 nuget PropertChanged.Fody 并构建类似的东西。 所以这就是我得到的。 此方法称为 Update属性,但真正的剂量是覆盖 属性Info,因此如果我的 属性Info 不是虚拟的,则此代码将不起作用。 那么是否可以仅更新我的 属性 信息集而不创建新的 属性 ?
private static void UpdateProperty(PropertyInfo propertyInfo, TypeBuilder typeBuilder,
MethodInfo raisePropertyChangedMethod)
{
// Update the setter of the class, here is the problem im creating new PropertyInfo
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyInfo.Name,
PropertyAttributes.None, propertyInfo.PropertyType, null);
// Create set method
MethodBuilder builder = typeBuilder.DefineMethod("set_" + propertyInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual , null, new Type[] { propertyInfo.PropertyType });
builder.DefineParameter(1, ParameterAttributes.None, "value");
ILGenerator generator = builder.GetILGenerator();
// Add IL code for set method
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Call, propertyInfo.GetSetMethod());
// Call property changed for object
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldstr, propertyInfo.Name);
generator.Emit(OpCodes.Callvirt, raisePropertyChangedMethod);
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(builder);
}
AFAIK 没有官方方法可以在运行时替换方法体(或 属性 setter)(除非它是动态方法)。不过,有很多方法可以做到这一点。参见
- Dynamically replace the contents of a C# method?
- How do I replace a method implementation at runtime?
但是当 属性 值更改时注入引发 PropertyChanged 方法的代码可以在编译时完成(这就是 PropertyChanged.Fody 所做的)并且看起来对我来说,这是比运行时代码修改更可取的解决方案。