2010-02-17 34 views
6

我知道如何根據Net Framework指南使用Events,但使用這種模式有什麼好處?符合網絡指南的事件有什麼好處?

http://msdn.microsoft.com/en-us/library/aa645739%28VS.71%29.aspx

.NET框架準則指示委託類型使用 一個事件應該採取兩個參數,指示所述事件的源「對象源」參數 ,和一個「e 「參數 封裝關於事件的任何附加信息。 「e」參數的類型應該從EventArgs類派生。對於不使用任何附加信息的事件 ,.NET Framework 已經定義了適當的委託類型:EventHandler。

a)我看到使用「對象源」值作爲第一個參數的好處,因爲有些情況下多個對象可以將它們的事件設置爲相同的方法。因此,例如,如果我們有10個對象,並且如果所有10個對象都將事件設置爲事件處理程序M,則在M內部,我們可以使用「對象發送者」參數值來標識事件調用的發起者。

  • 但據我所知,「對象源」參數只有在事件在實例方法內引發時纔有用。因此,如果事件是在靜態方法內部引發的,那麼「對象源」參數是沒有用的?!

b)根據Net Framework指南使用事件是否還有其他好處?

c)中無論是什麼好處可以是,爲什麼會他們出重量不必

  • 寫一個額外的代碼來把所需的參數爲從EventArgs的派生的對象的麻煩
  • 寫的附加事件處理程序中的代碼從EventArgs派生的對象中提取信息?

謝謝

+1

我認爲這將是很好的提'CancelEventArgs'爲好,因爲它可以提及的模式的有用的部分。 – stakx 2010-02-17 18:08:05

回答

10

據我看到它有兩大好處:

  • 人們編寫代碼使用該事件將識別模式,並立即知道如何使用事件
  • 該活動的簽名是以一種強大的方式精心製作的

第一個poi nt應該很明顯,不需要很多詳細說明。

至於第二點,這有兩個原因(在我看來)。首先,由於發件人是object,事件簽名可以被多種類型重複使用。其次,由於第二個參數是一個EventArgs decendant,所以當您引入您自己的EventArgs類時,可以稍後擴展此類,而不更改事件的簽名。

更新
回答問題:

我不知道你所說的「是 能夠延長EventArgs的不 改變事件的簽名」是什麼意思?

讓我們舉個例子,拿下面的類:

public class SomeClass 
{ 
    public event EventHandler<FileEventArgs> SomethingHappened; 
} 
public class FileEventArgs : EventArgs 
{ 
    public FileEventArgs(string filename) 
    { 
     Filename = filename; 
    } 
    public string Filename { get; private set; } 
} 

然後我們有一個消費者偵聽到SomethingHappened事件:

static void SomethingHappenedHandler(object sender, FileEventArgs e) 
{ 
    // do something intelligent 
} 

現在,讓我們說,我們要擴展我們在事件中傳輸的信息以及有關文件發生情況的信息:

public enum WhatHappened 
{ 
    Copy, 
    Rename, 
    Delete 
} 
public class FileEventArgs : EventArgs 
{ 
    public FileEventArgs(string filename, WhatHappened whatHappened) 
    { 
     Filename = filename; 
     WhatHappened = whatHappened; 
    } 
    public string Filename { get; private set; } 
    public WhatHappened WhatHappened { get; private set; } 
} 

現在,如果我們選擇在事件本身中將文件名作爲參數發送,則需要通過添加另一個參數來更改事件簽名,從而有效地打破所有偵聽事件的代碼。但是由於我們在上面的代碼中只是簡單地將另一個屬性添加到FileEventArgs類中,所以簽名保持不變,並且不需要更新偵聽器(除非他們想使用新添加的屬性)。

我是否在假設如果事件 是靜態方法中提出寫,然後 「對象源」參數是無 使用?

是的,這是正確的。我通常通過null作爲static事件(其實,非常罕見)的發件人參數。

+0

+1,以便稍後更改事件參數。 – OregonGhost 2010-02-17 18:04:00

+0

a)\t「當你引入你自己的EventArgs類時,這個類可以稍後擴展而不會改變事件的簽名。」我不確定你的意思是「能夠在不改變事件簽名的情況下擴展EventArgs」 ?! b)我是否假設在靜態方法內引發事件,那麼「對象源」參數是沒有用的?! – AspOnMyNet 2010-02-18 20:28:04

+1

@AspOnMyNet:我更新了我的答案。 – 2010-02-18 21:17:36

4

那麼標準方法的主要好處之一就是它可以在罐子上做它所描述的事實。 標準方法意味着任何開發人員都能立即看到您的代碼,並瞭解如何使用您的事件。

8

如果您遵守.NET Framework指南,不僅針對事件,而且針對所有事情,需要閱讀您的代碼或使用您的庫的人員將認識到這一點,從而使其變得更簡單。這總是一件好事,因爲你應該爲讀者編寫代碼,而不是爲了方便。 .NET的好處在於,從一開始就有一些標準指南,與成千上萬的C++等慣例相反,大多數人都知道並應用它。

標準事件處理程序簽名的附加好處是,您可以將更少的專用事件處理程序(例如EventHandler)分配給更專用類型的事件,從而在不需要附加數據的情況下簡化開發。它還使通過反射添加事件處理程序變得更加簡單,這在某些情況下可能很有用(例如某些對象模型的對象層次結構瀏覽器) - 我可以向您保證,通過反射處理任何事件的代碼是一件複雜的事情,我通過發佈每個事件的IL代碼來解決問題,我一直認爲這是最後的手段。

正如弗雷德裏克默克在寫的同時,這也使得事後擴展事件更容易,只需將參數添加到EventArgs派生類中,而不是添加到每個事件處理函數中。

+0

+1!我從來沒有意識到可以訂閱一個方法,該方法將一個EventArgs帶到一個帶有XXXEventArgs的事件中......現在你提到它了,它非常有意義! – 2010-02-17 19:44:52

3

個人而言,我不按本指南的所有,只爲工作時間將公佈一般重用

爲什麼呢?

  • ,因爲我並不總是需要知道事件
  • 的發送者,因爲移動代理參數 - 只有一種尤其是當 - 以一個單獨的類是矯枉過正

是的,我知道,爭論將來可能會改變。但YAGNI。坦率地說,當我必須改變事件委託中的參數時,編譯器會方便地告訴我每個使用它的地方,以便我可以檢查它們是否正確處理新的參數。如果我遵循標準並使用了自定義的EventArgs類,則必須手動搜索這些地方。

所以,像往常一樣,「這取決於」「用你自己的判斷」申請:-)