C# 用委托的新实例注销事件

C# 用委托的新实例注销事件,c#,events,C#,Events,这写的一样到控制台 EventHandler a = new EventHandler(control_RegionChanged); EventHandler b = new EventHandler(control_RegionChanged); if (a == b) { Console.WriteLine("Same!"); } else { Console.WriteLine(a.GetHashCode() + " " + b.GetHashCode()

这写的
一样到控制台

EventHandler a = new EventHandler(control_RegionChanged);
EventHandler b = new EventHandler(control_RegionChanged);

 if (a == b)
 {
     Console.WriteLine("Same!");
 }
 else
 {
     Console.WriteLine(a.GetHashCode() + " " + b.GetHashCode());
 }
执行此代码后,
EventHandler
是否未注册?

尝试使用

control.RegionChanged += new EventHandler(control_RegionChanged);
control.RegionChanged -= new EventHandler(control_RegionChanged);

这也应该可以(从内存中——还没有真正测试过)。至少它不会创建新的eventhandler引用。

是;在实例和
MethodInfo
上比较代理;如果这些都是相同的,那么它就会起作用。当尝试取消订阅匿名方法时会出现问题;在这种情况下,您必须保留对代理的引用才能取消订阅

因此:

这很好:

control.RegionChanged += control_RegionChanged
control.RegionChanged -= control_RegionChanged
但这风险更大:

control.SomeEvent += obj.SomeMethod;
//...
control.SomeEvent -= obj.SomeMethod;
使用匿名方法的正确过程是:

control.SomeEvent += delegate {Trace.WriteLine("Foo");};
//...
control.SomeEvent -= delegate {Trace.WriteLine("Foo");};

事实上是的。编译器是为你做的。我刚刚测试了它,并且——至少在我的测试中——在以这种方式添加和删除处理程序后,它工作了。这只是一种简写,编译器仍然会将其转换为一个新的EventHandler。@Lennaert:当然工作了,我从来没有说过它不工作。我说你最后一句话错了。
EventHandler handler = delegate {Trace.WriteLine("Foo");};
control.SomeEvent += handler;
//...
control.SomeEvent -= handler;