从DynamicObject中删除事件

时间:2011-01-25 17:59:00

标签: c# events reflection dynamic

我已成功将事件处理程序添加到动态对象中。但是,我无法删除它们。

dynamic d = new MyDynamicObject();
d.MyEvent += new EventHandler(this.MyHandler);
d.MyEvent -= new EventHandler(this.MyHandler);

当我添加事件处理程序时,我会以处理程序作为参数调用TrySetMember,但是,在删除它时,值为null。如果它为null,我应该如何知道从我的内部存储器中删除哪个处理程序用于该特定事件?

3 个答案:

答案 0 :(得分:1)

如果没有要查看的代码段,很难猜出问题可能是什么。我会发布一些简单有用的东西:

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

答案 1 :(得分:0)

我认为您需要保留对new EventHandler周围的引用并删除它:

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

答案 2 :(得分:-1)

你实际上不知道你要移除什么,因为它不像已经添加的静态事件那样工作,如果dlr没有看到静态事件属性则删除,它会在你做的时候动态执行以下等效操作+=-=

//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是一个MulticastDelegate,所以你应该把它想象成一个集合,所以如果它只有你要移除的事件处理程序,那么最后的set属性应该为null,因为什么都没有。如果您在混合中添加了更多事件,那将更加清晰。

//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

如果您必须以不同方式存储它并需要添加和删除,请创建一个存储类来包装您的行为,并确保将其返回到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;
    }
}