2011-09-06 52 views
0

我正在建立一個程序的靈活性,因爲它的目的已經改變。我想添加一個現有類將實現的接口。事件處理程序,現有的類到新的接口

現有類

public class ClassA 
{ 
    #region Events 
    public delegate void DataReceivedHandler(object sender, EventArgs e); 
    public delegate void DataSentHandler(object sender, EventArgs e); 
    public delegate void StatusUpdatedHandler(object sender, EventArgs e); 
    public event DataReceivedHandler DataReceived; 
    public event DataSentHandler DataSent; 
    public event StatusUpdatedHandler StatusUpdated; 
    #endregion 

    //rest of code here... 
} 

新界面

public interface IClassA 
{ 
    event EventHandler DataReceived; 
    event EventHandler DataSent; 
    event EventHandler StatusUpdated; 

    //rest of code here... 
} 

我的三個問題如下。

Q1。首先,我是否應該在課堂上宣佈我自己的代表,即public delegate void DataReceivedHandler,或者是否應該將這些代表移除,並將事件替換爲正常的EventHandler。即public event EventHandler DataReceived。鑑於這些事件不是通過事件傳遞數據,只是通知訂閱了某些內容的任何內容。 Q2302。與上述問題緊密相關。鑑於我正在改變這個類的屬性,即狀態(StatusUpdated)。將新狀態作爲自定義EventArgs傳遞是最佳做法,因此需要在原始代碼中使用自定義代理?由於它當前有效,因此事件被觸發,並且訂閱的類可以使用發件人值,即(發件人爲ClassA).Status。是否有最佳做法,還是僅僅取決於開發者?

Q3。現在已經過去了。關於界面的部分。我是否正確地聲明瞭接口中的DataReceived和其他事件,以匹配將被標記爲實現它的類。

回答

1

如果您需要接口方法的自定義委託,則應該單獨(在類之外)聲明它們,因爲它們不與特定的實現綁定。委託聲明可以像一個類一樣在接口內部進行。與代表的問題是他們都有相同的簽名EventHandler),因此是多餘的。

如果你不要在引發這些事件時需要傳遞任何數據,你可以使用一個普通的EventHandler委託。但是,我期望通過DataReceived事件獲得一些數據,因此您應該檢查這是否合理,並可能使用接受某些數據作爲參數的委託。

第三,您的接口事件簽名必須匹配類簽名。您不能在接口中使用EventHandler委託類型,並更改類中的簽名。

請注意,您也可以避免顯式聲明委託類型,並使用BCL提供的通用Action委託(從.NET 3.5開始)。在這種情況下,你可能會碰到這樣的:

public interface IClassA 
{ 
    event Action<IClassA, Data> DataReceived; 
    event Action<IClassA, Data> DataSent; 
    event Action<IClassA, Status> StatusUpdated; 
} 

後一種方法讓你有一個強類型sender參數(在EventHandler反對的object)的好處。

+0

我已經嘗試了這兩種方法,你和Jamiecs並感謝你們的答案。我更喜歡使用Action <>,因爲我已經看到它用於GUI調用,所以它是我習慣它的一個好主意。我用這種方法看到的唯一缺點是缺乏自動完成功能。我以前的事件,如果我在myClassA.StatusUpdated輸入+ = ....的+ =自動創建一個可以處理該事件,甚至是自定義事件參數的方法。通過使用動作,情況並非如此,您必須親自編寫該方法。 – JonWillis

+0

的另一個原因偏好是一個強類型的發送者,雖然這可以通過它似乎是一個委託來實現。 – JonWillis

+0

@Jon:你確定嗎?我從來沒有遇到過這樣的問題,不管委託簽名(鍵入'+ =',打兩次'Tab',應該生成方法存根)。 – Groo

1

在回答你的問題,當然這些都是見仁見智的,所以我會給我的:

A1)不,你是不正確的重新聲明自己XXXHandler代表,有一個在框架(EventHandler)完全匹配你的 - 一個很好的跡象你是「重新發明輪子」。

A2),我認爲,所謂的StatusChanged事件應通過新的(和潛在舊)狀態,任何用戶。然而,這仍然不是一個理由來實現自己的委託,作爲框架定義了一個通用的委託(EventHandler<TEventArgs>)出於這樣的目的。

A3)此刻你類的事件不匹配的接口,這意味着它將無法implemnt它沒有改變。

文檔:EventHandler<TEventArgs>

+0

比Groo更簡潔的回答,但我喜歡使用Action <>。除了他的回答評論中的一個缺點。 – JonWillis