3 回答

TA貢獻1765條經(jīng)驗 獲得超5個贊
EventHandler
是類型的委托void EventHandler(object sender, EventArgs e)
。所以訂閱事件的處理程序的簽名必須與此匹配。
Nowvoid OnTableChanged(SqlChangeNotifier sender, SqlNotificationEventArgs e)
比這更具體:它不能再接受任何 sender
對象,并且事件參數(shù)也必須是 type SqlNotificationEventArgs
。
現(xiàn)在的問題是,當引發(fā)事件時,事件的原始發(fā)送者將嘗試使用參數(shù)調(diào)用事件處理程序,object sender, EventArgs e
但您的方法需要更專業(yè)的類型。類型系統(tǒng)無法保證這些參數(shù)實際上是那些專用類型。
如果您需要這些類型,則需要將事件類型更改為限制性更強的委托類型。

TA貢獻1853條經(jīng)驗 獲得超6個贊
有關(guān)此類更改的總體主題,請參閱逆變和協(xié)方差。
請記住,事件系統(tǒng)只是調(diào)用一系列方法的奇特方式,您可以在運行時換出這些方法,因此如果您不能使用與引發(fā)事件時傳遞的完全相同的參數(shù)直接調(diào)用處理程序,那么事件系統(tǒng)也做不到。
與方法一樣,事件處理程序是逆變的,這意味著類型的委托EventHandler<SpecializedEventArgs>(假設(shè)SpecializedEventArgs : EventArgs)將接受簽名處理程序,public void Handler(object sender, EventArgs args)因為對事件的調(diào)用最終會使用對象調(diào)用處理程序,該SpecializedEventArgs對象可以EventArgs通過簡單的多態(tài)性隱式轉(zhuǎn)換為。IE以下將編譯:
public static event EventHandler<SpecializedEventArgs> Event;
public static void Handler(object sender, EventArgs args) { }
public static void Main() {
Event += Handler;
//...

TA貢獻1805條經(jīng)驗 獲得超9個贊
你不能那樣做,因為事件的訂閱者應(yīng)該得到一個派生實例,但發(fā)布者只能提供一個基礎(chǔ)實例。
你可以做相反的事情:
public static event KeyEventHandler ChangeDetected; // handler with derived args signature
private static void Program_ChangeDetected(object sender, EventArgs e) // base event args are OK
{
Console.WriteLine("ChangeDetected");
}
static void Main(string[] args)
{
ChangeDetected += Program_ChangeDetected;
ChangeDetected?.Invoke(null, new KeyEventArgs(default)); // base event args are NOT OK
}
- 3 回答
- 0 關(guān)注
- 106 瀏覽
添加回答
舉報