add和remove訪問器的編程用法,以及如何選擇性地呼叫事件訂閱者類的方法。
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AdvancedEvent{ //define a delegate delegate void NameChangedDelegate(string name, string newValue); class Program { static void Main(string[] args) { Customer c = new Customer(); Subscriber s1 = new Subscriber(c, "subscribe-A"); Subscriber s2 = new Subscriber(c, "subscribe-B"); Subscriber s3 = new Subscriber(c, "subscribe-C"); c.FirstName = "Kevin"; c.LastName = "Hoffman"; s2.Unsubscribe(); c.FirstName = "Joe"; c.MiddleName = "Scott"; Console.ReadLine(); } } class Subscriber // { private string subscribedId = "new subscriber"; private Customer myCustomer = null; private NameChangedDelegate ncDel = null; public Subscriber(Customer c, string subId) { subscribedId = subId; ncDel = new NameChangedDelegate(myCustomer_OnNameChanged); myCustomer = c; myCustomer.onNameChanged += ncDel; } void myCustomer_OnNameChanged(string name, string newValue) { Console.WriteLine("[{0}] Customer {1} changed to {2}.", subscribedId, name, newValue); } public void Unsubscribe() { myCustomer.onNameChanged -= ncDel; } public string SubscriberID { get { return subscribedId; } set { subscribedId = value; } } } class Customer { private string firstName; private string lastName; private string middleName; private event NameChangedDelegate onNameChange; // create the event by using the delegate defined public event NameChangedDelegate onNameChanged //define the details of the event { add { onNameChange += value; if (value.Target is Subscriber) { Console.WriteLine("Subscriber '{0}' just subscribed to OnNameChanged.", (((Subscriber)value.Target).SubscriberID)); } } remove { onNameChange -= value; if (value.Target is Subscriber) { Console.WriteLine("Subscriber '{0}' just subscribed to OnNameChanged.", (((Subscriber)value.Target).SubscriberID)); } } } public string FirstName { get { return firstName; } set { firstName = value; onNameChange("firstname", value); } } public string LastName { get { return lastName; } set { lastName = value; onNameChange("lastname", value); } } public string MiddleName { get { return middleName; } set { middleName = value; NotifyAllBut("subscribe-C", "middlename", value); } } private void NotifyAllBut(string subId, string name, string value) { foreach (NameChangedDelegate d in onNameChange.GetInvocationList()) { if (((Subscriber)d.Target).SubscriberID.ToUpper() != subId.ToUpper()) { d(name, value); } } } }}
類或對象可以通過事件向其他類或對象通知發生的相關事情。發送(或引發)事件的類稱為“發行者”,接收(或處理)事件的類稱為“訂戶”。
在這個例子中,Customer就是發行者,接收和處理事件訂戶就是Subscriber。整個事件的處理流程是如下設計的:
- 定義一個委託NameChangedDelegate綁定到訂戶Subscriber的事件的處理方法上myCustomer_OnNameChanged。
Delegate void NameChangedDelegate(string name, string newvalue); //為事件的處理方法聲明一個委託
Class Subscriber
{
Private NameChangedDelegate ncDel = null; // 將委託聲明為類的成員
public Subscrber(Customer c, string subId)
{
ncDel = new NameChangedDelegate(myCustomer_OnNameChanged); //將委託綁定到事件處理方法上
myCustomer = c;
myCustomer.OnNameChanged += ncDel; //為Customer類的OnNameChanged方法訂製處理方法,如果事件發生了,則激發myCustomer_OnNameChanged事件運行
}
}
- 在訂戶Subscriber類裡,寫出具體的事件處理方法。
Void myCustomer_OnNameChanged(string name, string newvalue)
{
//處理方法
}
- 以上的步驟交代好了,事件發生後的處理方法。但是事件還沒有編寫。現在開始寫關鍵的部分,編寫事件。
- 在Customer類裡面定義了2個事件。
Private event NameChangedDelegate onNameChange;
Public event NameChangedDelegate onNameChanged
{
Add//add訪問器
{
}
Remove//remove訪問器
{
}
}
- 首先來看看onNameChange的作用。
Public string FirstName
{
Get
{
Return firstName;
}
Set
{
firstName = value;
onNameChange(“firstname”, value);
}
}
onNameChange是NameChangedDelegate的一個執行個體,所以是onNameChange(“firstname”, value)和NameChangedDelegate委託的方法myCustomer_OnNameChanged具有相同的參數結構。
通過Debug知道,上面的關於FirstName屬性裡的onNameChange(“firstname”,value)語句只有在當customer執行個體的firstname值發生改變的時候,才會運行。同時運行myCustomer_OnNameChanged方法。至於為什麼,只有當customer執行個體的firstname值發生改變的時候,onNameChange(“firstname”,value)語句才運行。我想只有和這句話有關係了 onNameChange += value
- 分析onNameChanged事件。
public event NameChangedDelegate onNameChanged
{
add
{
onNameChange += value;
if (value.Target is Subscriber)
{
Console.WriteLine("Subscriber '{0}' just subscribed to OnNameChanged.", (((Subscriber)value.Target).SubscriberID));
}
}
remove
{
onNameChange -= value;
if (value.Target is Subscriber)
{
Console.WriteLine("Subscriber '{0}' just subscribed to OnNameChanged.", (((Subscriber)value.Target).SubscriberID));
}
}
}