c# – 有没有办法在设置类的任何属性时调用方法?
发布时间:2020-12-15 04:06:18 所属栏目:百科 来源:网络整理
导读:所以我要做的是在设置C#类中的任何属性时调用单个propertyWasSet()函数(相反,当获取时为propertyWasGot()).我还想知道调用哪个属性’get’. 我想保持一个’设置’属性的dictonary,并检查’??get’动作是否已经设置(并且如果没有则抛出错误). 我正在通过msdn
所以我要做的是在设置C#类中的任何属性时调用单个propertyWasSet()函数(相反,当获取时为propertyWasGot()).我还想知道调用哪个属性’get’.
我想保持一个’设置’属性的dictonary,并检查’??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() { } } 用法: 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); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- ruby-on-rails – 使用Rails和Paperclip导入旧数据
- VxWorks for PowerPC的内存分配
- 使用ReactiveCocoa实现iOS平台响应式编程
- xml – 为什么第一个apply-templates中没有select
- c – 是否可以在不向其传递参数的情况下获取函数的返回类型
- ruby-on-rails – 路由如何在rails中工作
- c# – Entity Framework核心:无法添加迁移:无参数构造函数
- mini-XML 中文文档
- ruby-on-rails – 如何使用I18n宝石翻译电子邮件正文?
- NSJSONSerialization iOS自带解析json