开发者

Removing an event from a DynamicObject

I have successfully added event handlers to my dynamic object. However, I am not able to remove them.

dynamic d = new MyDynamicObjec开发者_Python百科t();
d.MyEvent += new EventHandler(this.MyHandler);
d.MyEvent -= new EventHandler(this.MyHandler);

When I add the event handler, I get a call to TrySetMember with the handler as argument, however, when removing it the value is null. If it's null, how I am supposed to know which handler to remove from my internal storage of handlers for that particular event?


Hard to guess what the problem might be without a snippet to look at. I'll just post something simple that works:

using System;
using System.Dynamic;

class Program {
    static void Main(string[] args) {
        dynamic obj = new MyDynamicObject();
        obj.MyEvent += new EventHandler(handler);
        obj.MyEvent(null, EventArgs.Empty);
        obj.MyEvent -= new EventHandler(handler);
    }
    static void handler(object sender, EventArgs e) { }
}

class MyDynamicObject : DynamicObject {
    private EventHandler dlg = new EventHandler(delegate { });
    public override bool TryGetMember(GetMemberBinder binder, out object result) {
        result = dlg;
        return true;
    }
    public override bool TrySetMember(SetMemberBinder binder, object value) {
        dlg = (EventHandler)value;
        return true;
    }
}


I think you need to keep a reference to your new EventHandler around and remove that:

var MyEventHandler = new EventHandler(this.MyHandler);
d.MyEvent += MyEventHandler;
d.MyEvent -= MyEventHandler;


You actually don't know what you are removing, because it doesn't work like static events which have add,remove if the dlr doesn't see a static event property, it does the following equivalent operations dynamically when you do += and -=.

//d.MyEvent += new EventHandler(this.MyHandler);
var temp = d.MyEvent; //temp is null
temp += new EventHandler(this.MyHandler) //temp is now MyHandler
d.MyEvent = temp; //set it back

//d.MyEvent -= new EventHandler(this.MyHandler);
var temp = d.MyEvent;  //temp is MyHandler
temp -= new EventHandler(this.MyHandler)  //temp is now null
d.MyEvent = temp; //set it back

EventHandler is a MulticastDelegate so you should think of it like a collection, so if it only had the event handler that you are removing, the set property at the end should be null, as there is nothing left. If you had more events added in the mix it would be clearer.

//d.MyEvent += new EventHandler(this.MyHandler);
var temp = d.MyEvent; //temp is null
temp += new EventHandler(this.MyHandler) //temp is now MyHandler
d.MyEvent = temp; //set it back

//d.MyEvent += new EventHandler(this.MyHandler2);
var temp = d.MyEvent; //temp is MyHandler
temp += new EventHandler(this.MyHandler2) //temp is now MyHandler,MyHandler2
d.MyEvent = temp; //set it back

//d.MyEvent -= new EventHandler(this.MyHandler);
var temp = d.MyEvent;  //temp is  MyHandler,MyHandler2
temp -= new EventHandler(this.MyHandler)  //temp is now MyHandler2
d.MyEvent = temp; //set it back

If you have to store it differently and need an add and remove then make a storage class to wrap your behavior and make sure you return it on your TryGet.

public DelegateStoreage<T>{

 public void Add(T del){
    //Do your stuff
}
 public void Remove(T del){
    //Do your stuff
 }
 public static T operator +(DelegateStoreage<T> x, T y)
    {
        x.Add(y)
        return x
    }

    public static T operator -( DelegateStoreage<T> x, T y)
    {
        x.Remove(y)
        return y;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜