2012-04-20 176 views
1

到目前爲止,在我對c#的有限使用中,我訂閱了幾個事件。 爲什麼以下兩個代碼片段使用兩個不同的單詞EventHandlerElapsedEventHandlerEventHandler和ElapsedEventHandler有什麼區別?

 myProcess = new Process(); 
     myProcess.StartInfo.FileName = @"notepad.exe"; 
     myProcess.Exited += new EventHandler(MyProcessExited); 

相比:

 myTimer = new System.Timers.Timer(tickLength); 
     myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed); 

是針對其事件我使用的對象,這些話EventHandlerElapsedEventHandler?還是有一整套對象,我必須使用「EventHandler」和不同的對象,我必須使用「ElapsedEventHandler」? (即對於我們使用的對象集X,我們使用xxxxxEventHandler等)

回答

4

這些詞是EventHandler和ElapsedEventHandler特定於我正在使用的事件的 對象嗎?

這個詞是代表的名字。它們是特定於信息的,它是從對象傳遞來的,它將事件引發給該事件的訂閱者。閱讀下面傳遞的事件,代表和參數。

C#中的事件是類的一種方式,當對象發生一些有趣的事情時,可以向該類的客戶端提供通知。事件使用delegates進行聲明。

所以,如果你想通知你的對象發生了一些有趣的東西客戶端,你可以聲明委託:

public delegate void SomethingHappenedDelegate(); 

而在你的類中聲明該類型的事件:

class Foo 
{ 
    public event SomethingHappenedDelegate SomethingHappened; 

    // other code, which raises SomethingHappened event 
    // when something interesting happened 
} 

當這個類的客戶希望被通知發生了一些有趣的事情時,他們應該訂閱SomethingHappened事件。和事件處理程序的簽名必須匹配(在這種情況下SomethingHappenedDelegate)事件的類型:

static void Main(string[] args) 
{ 
    Foo foo = new Foo(); 
    foo.SomethingHappened += new SomethingHappenedDelegate(Foo_SomethingHappened);    
} 

// this method should be: void MethodName() 
static void Foo_SomethingHappened() 
{ 
    // you notified, that something happened 
} 

當你需要通知客戶端時,通過一些額外的數據,你應該使用不同的委託類型,這需要一些論據。例如,如果你想傳遞一些信息給客戶,改變事件的委託類型:

public delegate void SomethingHappenedDelegate(string message); 

現在你應該改變事件處理程序來對應這種委託類型:

static void Foo_SomethingHappened(string message) 
{ 
    // you notified, that something happened and you recieved a message 
} 

另一個例子,如果我們想通過對象的實例,它引發的事件,以及一些額外的參數信息和時間:

public delegate void SomethingHappenedDelegate(object sender, string message, DateTime time); 

那麼我們應該有相同的簽名事件處理程序:

static void Main(string[] args) 
{ 
    Foo foo1 = new Foo(); 
    foo1.SomethingHappened += new SomethingHappenedDelegate(Foo_SomethingHappened); 
    Foo foo2 = new Foo(); 
    foo2.SomethingHappened += new SomethingHappenedDelegate(Foo_SomethingHappened); 
} 

// we use same event handler for all SomethingHappened events 
static void Foo_SomethingHappened(object sender, string message, DateTime time) 
{ 
    Foo foo = sender as Foo; // now we get object, which raised event 
    // and we can use message and time 
} 

所以,所有事件都有一些委託類型。該委託的定義描述哪些參數應該接收方法,哪些將處理事件。在您的代碼中,您使用兩個事件 - Process.ExitedTimer.Elapsed。讓我們看看這些事件是如何定義的:

public event EventHandler Exited; 
public event ElapsedEventHandler Elapsed; 

這裏你可以看到不同類型的代表:

public delegate void EventHandler(object sender, EventArgs e); 
public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e); 

你可以從定義看,這些代表有相同的第一個參數(發件人),和不同的最後參數。所以,這些事件的處理者也應該有不同的簽名,這應該與這些代表相匹配。

您可能想知道,爲什麼第二個參數的名稱以EventArgs結尾。如果你想通知其他對象,SomethingHappened,然後按照約定在C#中存在:

  • 事件名稱應該是SomethingHappened
  • 如果客戶需要傳遞一些額外的數據,這些數據封裝在對象,它派生來自EventArgs類:SomethingHappenedEventArgs
  • 事件委託應該EventHandler(如果沒有額外的信息應該傳遞給客戶端),或者它應該是通用型EventHandler<SomethingHappenedEventArgs>的,或者它應該是自定義的名稱爲SomethingHappenedEventHandler和簽名無效(對象發件人,SomethingHappenedEventArgs E)
  • 委託

閱讀全文here

+0

你的名字似乎有點不合適_lazy_ berezovsky ....感謝您的幫助 – whytheq 2012-04-20 11:43:24

+0

@whytheq我害怕如果我不是懶惰會發生什麼事情:) – 2012-04-20 13:05:49

+0

我癡迷於嘗試學習C#在此刻.. ..這是從我目前的知識(VBA和SQL)如此巨大的跳躍,像你的答案讚賞,但有點可怕! – whytheq 2012-04-20 14:06:50

0

不,事件名稱是框架設計器選擇的問題+它們與表示任何特定對象事件的代表緊密耦合。

事件處理defininton是:

[Serializable] 
[ComVisible(true)] 
public delegate void EventHandler(object sender, EventArgs e); 

ElapsedEventHandler definiton是:

public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e); 

正如你可以看到他們是不同類型的delegate

+0

...所以對於不同的對象(不是一個進程或計時器)它可能是上述之一;或者它可能是一個不同的處理程序? – whytheq 2012-04-20 08:27:15

+0

這是一個選擇的問題。如果你寫自己的班級,你可以擁有他們兩個,或者他們中的一個。在這種情況下,爲Timer定義了一個委託類型,這更適合於它的架構。只是建築師選擇的問題。 – Tigran 2012-04-20 08:29:39