在这些代表中:
EventHandler
public delegate void EventHandler(object sender,EventArgs e);
FormClosingEventHandler
public delegate void FormClosingEventHandler(object sender,FormClosingEventArgs e);
FormClosingEventArgs
继承自 EventArgs
. 为什么我不能用 EventHandler
委托的事件处理程序绑定 FormClosing
事件?
我知道事件处理程序的签名必须与其委托匹配,但为什么它不支持匹配继承的类型?
2 回答
好吧,这很有意思......
您可以使用兼容类型的方法组转换绑定事件处理程序:
这实际上会创建
FormClosingEventHandler
的实例,而不是EventHandler
.但是,您无法直接订阅EventHandler类型的现有委托:
...但是如果类型兼容,您可以基于现有委托创建新委托:
基本上你需要记住所有语法糖都有效地调用这样的方法:
方法具有以下特征的签名:
现在请记住,虽然它们具有兼容的签名,但是从
EventHandler
到FormClosingHandler
没有可用的参考转换 . 它不像一个人从另一个继承 .通用协方差/逆变会让它变得更加混乱,但我们暂时将它留在那里......希望能给你一些可以咀嚼的东西以及围绕这些限制的选择 .
直接指向对象方法的委托包含三条信息:
方法应该作用的目标对象,或者静态方法的情况下为“null”
对作用于该类型对象的函数的引用,或者如果目标为“null”则为静态函数 .
委托本身的类型 .
通过使用
Delegate.Combine
组合总共N个单播代表生成的委托将包含N个目标,N个方法和一个委托类型 . 鉴于使用Delegate.Combine
和Delegate.Remove
的(IMHO相当icky和不幸)方式,系统无法允许Combine
的现有用途接受不同类型的委托 .例如,例程可能需要
EventHandler<IFoo>
. 如果类Moe
和Larry
都实现IFoo
和IBar
,则此例程应该能够接受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>
) .