因此,我想做的是在设置 C# 类中的任何属性时调用单个 propertyWasSet() 函数(相反,在获取属性时调用 propertyWasGot() )。我还想知道调用了哪个属性的“get”。
我想维护一个“设置”属性的字典,并检查“获取”操作是否已设置(如果尚未设置,则抛出错误)。
我一直在浏览 msdn 文档以了解反射、委托等...,但我不完全确定这是可能的。
有没有办法做到这一点?或者在调用这些可以在基类或其他东西中拦截的函数之一时触发事件?
前一周我为 Set 编写了一个拦截器,它可以轻松地扩展为 Get,它使用 RealProxy,这意味着您的基类需要从 MarshalByRefObject 派生。
另一个奇特的选择是让您的类抽象,并使用 Reflection Emit 构造一个包装所有属性的具体类。
您也可以查看代码生成器来解决这个问题或 PostSharp...
该解决方案的性能并不出色,但对于大多数 UI 绑定来说应该足够快了。可以通过生成用于代理调用的 LCG 方法来改进它。
public interface IInterceptorNotifiable {
void OnPropertyChanged(string propertyName);
}
/// <summary>
/// A simple RealProxy based property interceptor
/// Will call OnPropertyChanged whenever and property on the child object is changed
/// </summary>
public class Interceptor<T> where T : MarshalByRefObject, IInterceptorNotifiable, new() {
class InterceptorProxy : RealProxy {
T proxy;
T target;
EventHandler<PropertyChangedEventArgs> OnPropertyChanged;
public InterceptorProxy(T target)
: base(typeof(T)) {
this.target = target;
}
public override object GetTransparentProxy() {
proxy = (T)base.GetTransparentProxy();
return proxy;
}
public override IMessage Invoke(IMessage msg) {
IMethodCallMessage call = msg as IMethodCallMessage;
if (call != null) {
var result = InvokeMethod(call);
if (call.MethodName.StartsWith("set_")) {
string propName = call.MethodName.Substring(4);
target.OnPropertyChanged(propName);
}
return result;
} else {
throw new NotSupportedException();
}
}
IMethodReturnMessage InvokeMethod(IMethodCallMessage callMsg) {
return RemotingServices.ExecuteMessage(target, callMsg);
}
}
public static T Create() {
var interceptor = new InterceptorProxy(new T());
return (T)interceptor.GetTransparentProxy();
}
private Interceptor() {
}
}
Usage:
class Foo : MarshalByRefObject, IInterceptorNotifiable {
public int PublicProp { get; set; }
public string lastPropertyChanged;
public void OnPropertyChanged(string propertyName) {
lastPropertyChanged = propertyName;
}
}
[Test]
public void TestPropertyInterception() {
var foo = Interceptor<Foo>.Create();
foo.PublicProp = 100;
Assert.AreEqual("PublicProp", foo.lastPropertyChanged);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)