有没有一种方法,当一个类中的任何属性设置为调用一个方法? [英] Is there a way to call a method when any property of a class is set?

查看:135
本文介绍了有没有一种方法,当一个类中的任何属性设置为调用一个方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我想要做的是调用一个propertyWasSet()函数时,C#类中的任何属性设置(相反,propertyWasGot()时,它是获得)。我也想知道哪个属性的GET被调用。

So what I'm trying to do is call a single propertyWasSet() function when any property within a C# class is set (conversely, propertyWasGot() when it is get). I would also like to know which property's 'get' was invoked.

我要维护的设置属性的dictonary,检查经得到如果他们已经确定的行动,但(并抛出一个错误,如果它一直没有)。

I would like to maintain a dictonary of properties that are 'set', and check upon the 'get' action if they have been set yet (and throw an error if it hasn't been).

我翻翻MSDN文档反射,代表等......,但我不能完全肯定这是可能的。

I've be looking through msdn documentation for reflection, delegates, etc..., but I'm not entirely sure this is possible.

有没有办法做到这一点?或者在调用这些功能,可以在基类或某事被截获一个消防事件?

Is there a way to do this? or fire an event upon calling one of these functions that can be intercepted in a base class or something?

推荐答案

我写了一个拦截器其他周设置,可以很容易地扩展为获取,它使用RealProxy,这意味着你的基类,需要派生了MarshalByRefObject的。

I wrote an interceptor the other week for Set which can easily be extended for Get, it uses RealProxy, which means your base class needs to derive off MarshalByRefObject.

另外一个花哨的选择是让你的抽象类,并使用反射发出来构造包装了所有属性的具体类。

Another fancy option is to have your class abstract, and use Reflection Emit to construct a concrete class that wraps up all the properties.

另外你可以看看代码生成器来解决这个问题还是PostSharp ...

Also you could look at code generators to get around this or PostSharp...

性能该解决方案是不是恒星,但它应该是足够快于大多数用户界面绑定。它可以通过生成用于代理调用LCG方法加以改进。

Performance for this solution is not stellar, but it should be plenty fast for most UI binding. It could be improved by generating LCG methods for proxy invocation.

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);

    }
}

这篇关于有没有一种方法,当一个类中的任何属性设置为调用一个方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆