C# 在运行时替换属性设置器方法

C# 在运行时替换属性设置器方法,c#,reflection,C#,Reflection,我有许多对象都共享一个公共基类,我希望拦截所有设置属性值的调用,并记录这些调用是否是基于每个实例设置的 我可以在运行时用反射替换属性的Set方法吗?如果您的基类派生自ContextBoundObject,则可以在不同的上下文中(在相同的AppDomain中)创建对象并截获方法调用(这就是属性)并将您自己的消息接收器插入远程处理接收器链 这里有一个例子 一种方法是使属性虚拟,并在运行时通过反射emit创建一个子类,该子类覆盖属性,添加代码。然而,这是高级的,并且要求您始终确保创建子类(因此代码中没

我有许多对象都共享一个公共基类,我希望拦截所有设置属性值的调用,并记录这些调用是否是基于每个实例设置的


我可以在运行时用反射替换属性的Set方法吗?

如果您的基类派生自
ContextBoundObject
,则可以在不同的上下文中(在相同的
AppDomain
中)创建对象并截获方法调用(这就是属性)并将您自己的消息接收器插入远程处理接收器链

这里有一个例子


一种方法是使属性虚拟,并在运行时通过反射emit创建一个子类,该子类覆盖属性,添加代码。然而,这是高级的,并且要求您始终确保创建子类(因此代码中没有“新的”)

但是,;我想知道简单地实现INotifyPropertyChanged和处理事件是否更简单。另一种选择是首先将处理构建到常规类中。有一些方法可以减少重复性,特别是如果您有一个公共基类,可以在其中添加

protected void SetField<T>(ref T field, T value)
{
    if(!EqualityComparer<T>.Default.Equals(field,value))
    {
        field = value;
        // extra code here
    }
}

您不能在运行时直接替换它。如果财产是虚拟的,您可以像Castle一样使用
DynamicProxy
,为您创建一个扩展您的类型的代理类型,它的工厂可以用来获取一个类,该类可以截取它的方法

或者,您可以沿着
ContextBoundObject
路线,或者
Enterprise Libaries Policy Injection

请注意,ContextBoundObject比Castle的动态代理慢得多,但您不必将方法声明为虚拟。策略注入只允许在调用之前或之后插入通知,因此如果出于任何原因反对调用,则无法停止调用

如果您可以将此作为编译后步骤来处理,那么可以使用PostSharp或Mono.Cecil


我个人正在开发我自己的动态代理,它允许用委托替换方法,但它还没有准备好用于石灰灯。

这与我现在拥有的非常接近,谢谢。这确实完成了任务,但意味着我必须手动拦截所有调用。这篇文章确实有些过火,但确实强调了这是可以完成的,我将尝试这样做,但没有属性。谢谢,当我知道更多的时候,我会发布一些更新。
private int foo;
public int Foo {
    get { return foo; }
    set { SetField(ref foo, value); }
}