2012-06-28 21 views
0

我不確定在C#中這是否可能,但我希望在具有強類型「發件人」參數的抽象類中有事件。C#強類型繼承事件的「發件人」

有我的代碼

abstract class Base 
{ 
    public degate void MyDelegate(Base sender, object arg); 
    public event MyDelegate SomeEvent; 

    protected void RaiseSomeEvent(object arg) 
    { 
     if (SomeEvent != null) 
      SomeEvent(this, arg) 
    } 
} 

class Derived : Base 
{ 
    // ? 
} 

var obj = new Derived(); 
obj += EventHandler; 

public void EventHandler(Derived sender, object arg) 
{ 

} 

所以是可以通過manipuling通用的where子句的例子嗎?

+0

難道你試圖運行這個代碼? – Nas

+0

編譯器說EventHandler對委託MyDelegate沒有正確的簽名。 – Tim

回答

2

你絕對可以使它通用 - 但你不會真的想要在你給的情況下。

Base.SomeEvent不知道(在編譯時)它是什麼類型 - 所以你不能讓它取決於某種類型的參數,這將是「正確的類型」。您可以做這樣可怕的事情:

abstract class Base<T> where T : Base 
{ 
    delegate void MyDelegate(T sender, object arg); 

    public event MyDelegate SomeEvent; 

    protected void RaiseSomeEvent(object arg) 
    { 
     if (SomeEvent != null) 
      SomeEvent((T) this, arg) 
    } 
} 

(您可能需要(T) (object) this使編譯器高興)

然後:

class Derived : Base<Derived> 

但它變得非常難看,而且也沒有什麼可以阻止這種情況發生:

class Evil : Base<Derived> 

在這一點上,當事件發生時,演員陣容將失敗。

我想建議,如果你真的想肯定的是,發件人是正確的類型,你忽視了sender參數和捕捉你使用首先訂閱變量:

Derived derived = new Derived(); 
derived.SomeEvent += (ignored, arg) => DoSomething(derived, arg); 
+0

但是,如果我使用匿名方法,那麼我不能取消訂閱該方法,並且這是我的程序中絕對需要的。 我發現解決方案的泛型類更加可行,以我的觀點來看,檢查泛型類型是否是好的並不是什麼大不了的事情,我可以簡單地使用在裝配負載上使用反射的例程來做到這一點。 – Tim

+0

但是我仍然陷入困境,如果我有像AnotherDerived:派生,我不會有SomeEvent =>(AnotherDerived,對象),但SomeEvent =>(派生,對象)。如果派生成爲派生的我將無法將其作爲Derived()派生出來,但派生的新派生()並且非常難看。 – Tim

+0

經過一番研究,我決定在WPF路由事件中植入我自己的事件系統,雖然反思我會適當地投下我的觀點。 – Tim