为什么事件不支持绑定继承类型?

在这些代表中:

EventHandler

public delegate void EventHandler(object sender,EventArgs e);

FormClosingEventHandler

公共委托无效FormClosingEventHandler(对象发件人,FormClosingEventArgs e);

FormClosingEventArgsEventArgs继承。 为什么我无法将FormClosing事件与EventHandler委托的事件处理程序绑定?

我知道事件处理程序的签名必须匹配它的委托,但为什么它不支持匹配的继承类型?


嗯,这很有趣...

您可以使用兼容类型的方法组转换来绑定事件处理程序:

public void GenericHandlerMethod(object sender, EventArgs e) {}

...
// Valid
foo.FormClosingEvent += GenericHandlerMethod;

这实际上会创建FormClosingEventHandler一个实例,而不是EventHandler

但是,您无法直接订阅EventHandler类型的现有委托:

EventHandler genericHandler = GenericHandlerMethod;
// Invalid
foo.FormClosingEvent += genericHandler;

...但是如果类型兼容,您可以基于现有的代理创建新的代理:

EventHandler generic = GenericHandlerMethod;
FormClosingEventHandler closingHandler = new FormClosingEventHandler(generic);
// Valid
foo.FormClosingEvent += closingHandler;

基本上你需要记住,所有的语法糖都有效地调用了这样的方法:

foo.AddFormClosingHandler(handler);

该方法的签名为:

public void AddFormClosingHandler(FormClosingHandler handler)

现在请记住,尽管它们具有兼容的签名,但没有从EventHandlerFormClosingHandler参考转换。 它不像一个从另一个继承。

它更容易混淆泛型协变/逆变,但我们现在就把它留在那里...希望这给了你一些东西来咀嚼和选择工作的限制。


直接指向对象方法的委托包含三条信息:

  • 该方法应该在其上执行的目标对象,或者在静态方法的情况下为“空”
  • 作用于该类型对象的函数的引用,或者目标为“null”时的静态函数。
  • 代表本身的类型。

    使用Delegate.Combine合并总共N个单播代表的委托将包含N个目标,N个方法和一个委托类型。 鉴于使用Delegate.CombineDelegate.Remove方法(恕我直言,相当不幸和不幸),系统无法允许Combine现有用法接受不同类型的Delegate.Remove

    例如,一个例程可能需要一个EventHandler<IFoo> 。 如果MoeLarry类都实现IFooIBar ,那么这样的例程应该能够接受EventHandler<Moe>EventHandler<Larry> 。 如果每个委托类型都有自己的Combine定义,则可以为EventHandler<IFoo>.Combine()一个类型为EventHandler<Moe>的代表和一个EventHandler<Larry> ,并让它生成一个组合的委托处理程序键入EventHandler<IFoo> 。 不幸的是,对于所有委托类型,都有一个Delegate.Combine()方法,并且它无法查看EventHandler<Moe>EventHandler<Larry>并找出合并委托的类型(即使Delegate.Combine有能力识别两种事件处理程序可以投入的类型,但无法知道是否使用EventHandler<IFoo>EventHandler<IBar> )。

    链接地址: http://www.djcxy.com/p/35699.html

    上一篇: Why events does not support binding inherited types?

    下一篇: How do I call an event method in c#?