一個物件可以有三種東西:
其中,一個 event 可以有多個 handlers 。 利用 event - handler 語法,我們可以建立一個 Notification system 。[註1] [註2]
若是要利用 event - handler 設計一個 Notification 機制,必須先確定下列3件事:
1. 誰有event,並且如何raise這個event
2. 誰handle這個event (也就是誰實作 callback function)
3. 兩者如何連結
以下用 Button 與 Form 做個例子:
1. Button 有 Clicked event,並且 user 透過 UI 來 raise 這個 event
2. Form 會 handle這個 Clicked event
3. Form 的 Constructor 實作把 button.Clicked 與 callback function 作連結 ( += )
再舉個 Queue 與 Producer 的例子:
當 Queue 有空位的時候,Queue物件 '通知' Producer物件進行 enqueue。(Queue 發出Event 給 Producer)
仿照 Button 與 Form 的設計如下:
1. Queue 有 NotifyToEnqueu 的 event,並且實作 OnNotifyToEnqueue() 讓 user (client code) 來raise 這個event,如下:
public event EventHandler NotifyToEnqueue;
protected virtual void OnNotifyToEnqueue()
{
if (NotifyToEnqueue != null) // null means no subscribe
{
NotifyToEnqueue(this, EventArgs.Empty); // raise event
// Or, you can write like:
// NotifyToEnqueue.Invoke(this, EventArgs.Empty);
}
}
2. Producer 會 handle 這個 NotifyToEnqueu event,如下:
private void Queue_NotifyToEnqueue(object sender, EventArgs e)
{
m_MyQueue.Enqueue("aaa");
}
3. Producer 的 Constructor 實作把 queue.NotifyToEnqueue 與 Queue_NotifyToEnqueue 作連結 (+= ), 如下:
public Producer(MyQueue queue)
{
m_MyQueue = queue;
m_MyQueue.NotifyToEnqueue += Queue_NotifyToEnqueue; // subscribe
}
所以,當呼叫 OnNotifyToEnqueue() 的時候, Producer物件就會進行 enqueue
[註1]
event 這個物件(ex: NotifyToEnqueue)的 invocations list 可用來儲存多種方法 (ex: Queue_NotifyToEnqueue方法)
要使用這些方法,只要呼叫 Invoke() 即可。 ex: NotifyToEnqueue.Invoke();
[註2]
An Event declaration adds a layer of abstraction and protection on the delegate instance.
This protection prevents clients of the delegate from resetting the delegate and its invocation list
and only allows adding or removing targets from the invocation list.
- Property (ex: public string Name = "Peter";)
- Method (ex: public void Convert() {...} )
- Event (ex: public event EventHandler Click;)
其中,一個 event 可以有多個 handlers 。 利用 event - handler 語法,我們可以建立一個 Notification system 。[註1] [註2]
若是要利用 event - handler 設計一個 Notification 機制,必須先確定下列3件事:
1. 誰有event,並且如何raise這個event
2. 誰handle這個event (也就是誰實作 callback function)
3. 兩者如何連結
以下用 Button 與 Form 做個例子:
1. Button 有 Clicked event,並且 user 透過 UI 來 raise 這個 event
2. Form 會 handle這個 Clicked event
3. Form 的 Constructor 實作把 button.Clicked 與 callback function 作連結 ( += )
再舉個 Queue 與 Producer 的例子:
當 Queue 有空位的時候,Queue物件 '通知' Producer物件進行 enqueue。(Queue 發出Event 給 Producer)
仿照 Button 與 Form 的設計如下:
1. Queue 有 NotifyToEnqueu 的 event,並且實作 OnNotifyToEnqueue() 讓 user (client code) 來raise 這個event,如下:
public event EventHandler NotifyToEnqueue;
protected virtual void OnNotifyToEnqueue()
{
if (NotifyToEnqueue != null) // null means no subscribe
{
NotifyToEnqueue(this, EventArgs.Empty); // raise event
// Or, you can write like:
// NotifyToEnqueue.Invoke(this, EventArgs.Empty);
}
}
2. Producer 會 handle 這個 NotifyToEnqueu event,如下:
private void Queue_NotifyToEnqueue(object sender, EventArgs e)
{
m_MyQueue.Enqueue("aaa");
}
3. Producer 的 Constructor 實作把 queue.NotifyToEnqueue 與 Queue_NotifyToEnqueue 作連結 (+= ), 如下:
public Producer(MyQueue queue)
{
m_MyQueue = queue;
m_MyQueue.NotifyToEnqueue += Queue_NotifyToEnqueue; // subscribe
}
所以,當呼叫 OnNotifyToEnqueue() 的時候, Producer物件就會進行 enqueue
[註1]
event 這個物件(ex: NotifyToEnqueue)的 invocations list 可用來儲存多種方法 (ex: Queue_NotifyToEnqueue方法)
要使用這些方法,只要呼叫 Invoke() 即可。 ex: NotifyToEnqueue.Invoke();
[註2]
An Event declaration adds a layer of abstraction and protection on the delegate instance.
This protection prevents clients of the delegate from resetting the delegate and its invocation list
and only allows adding or removing targets from the invocation list.
沒有留言:
張貼留言