简体   繁体   English

在C#中绑定/取消绑定

[英]bind/unbind in C#

how can I implement analog of bind / unbind like in jQuery? 如何在jQuery中实现绑定/取消绑定的模拟?

class MyDataType<T>
{
    private List<T> data;
    ...
    public void Add(T value)
    {
        data.Add(value);
    }
    ...
}

...
MyDataTypeObject.Bind("Add",()=>Console.WriteLine("OnAdd"));
...
MyDataTypeObject.UnBind("Add");
...

You can mimic it but only for predefined methods using Events. 您可以模仿它,但只能模仿使用事件的预定义方法。

class MyDataType<T>
{
    EventHandler<EventArgs> OnAdded;

    private RaiseOnAdded() 
    {
        var onAdded = OnAdded
        if(onAdded != null) 
        {
           onAdded(this, new EventArgs());
        } 
    }

    private List<T> data;
    ...
    public void Add(T value)
    {
        data.Add(value);
        RaiseOnAdded(); // <-- Add knows to call OnAdded(..) 
    }
    ...
}

var hander = (s, e)=>Console.WriteLine("OnAdd"));

MyDataTypeObject.OnAdded  += handler;

MyDataTypeObject.OnAdded  -= handler;

You could do this using Castle DynamicProxy. 您可以使用Castle DynamicProxy做到这一点。 First, create abstract base class that contains the Bind() and Unbind() methods and a dictionary to hold the invocations: 首先,创建包含Bind()Unbind()方法的抽象基类,以及用于保存调用的字典:

public abstract class BindableBase
{
    private readonly Dictionary<string, Action> m_boundMethods =
        new Dictionary<string, Action>();

    protected Dictionary<string, Action> BoundMethods
    {
        get { return m_boundMethods; }
    }

    public void Bind(string method, Action action)
    {
        if (!m_boundMethods.ContainsKey(method))
            m_boundMethods.Add(method, null);

        m_boundMethods[method] += action;

    }

    public void Unbind(string method, Action action)
    {
        if (m_boundMethods.ContainsKey(method))
        {
            m_boundMethods[method] -= action;

            if (m_boundMethods[method] == null)
                m_boundMethods.Remove(method);
        }
    }
}

Then create concrete class that implements BindableBase . 然后创建实现BindableBase具体类。 You need to make any methods you want to intercept virtual: 您需要使任何要拦截虚拟的方法:

public class Foo<T> : BindableBase
{
    private readonly List<T> m_data = new List<T>();

    public virtual void Add(T value)
    {
        m_data.Add(value);
    }
}

Then create the interceptor that intercepts calls to any virtual methods and call the appropriate delegate from the dictionary: 然后创建拦截器来拦截对任何虚拟方法的调用,并从字典中调用适当的委托:

class Interceptor : IInterceptor
{
    private static readonly PropertyInfo BoundMethodsProperty =
        typeof(BindableBase).GetProperty(
            "BoundMethods", BindingFlags.Instance | BindingFlags.NonPublic);

    public void Intercept(IInvocation invocation)
    {
        var boudMethods =
            (Dictionary<string, Action>)BoundMethodsProperty.GetValue(
                invocation.InvocationTarget, null);

        invocation.Proceed();

        string method = invocation.Method.Name;

        Action action;
        if (boudMethods.TryGetValue(method, out action))
            action();
    }
}

Finally, it's just a matter of generating the proxy and using it: 最后,只需要生成代理并使用它即可:

var proxyGenerator = new ProxyGenerator();
Foo<int> foo = proxyGenerator.CreateClassProxy<Foo<int>>(new Interceptor());
foo.Bind("Add", LogAdd);
foo.Add(42);
foo.Unbind("Add", LogAdd);
foo.Add(43);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM