搬瓦工vps做網(wǎng)站速度怎么樣營銷方案怎么寫
目錄
一、委托的發(fā)布和訂閱
1.訂閱操作符號“+="和取消訂閱操作符號“-=”
2.示例源碼
二、事件的發(fā)布和訂閱
三、EventHandler類
四、Windows事件
????????C#中的事件是指某個類的對象在運行過程中遇到的一些特定事情,而這些特定的事情有必要通知給這個對象的使用者。當發(fā)生與某個對象相關的事件時,類會使用事件將這一對象通知給用戶,這種通知即稱為“引發(fā)事件”。引發(fā)事件的對象稱為事件的源或發(fā)送者。
一、委托的發(fā)布和訂閱
????????由于委托能夠引用方法,而且能夠鏈接和刪除其他委托對象,因而就能夠通過委托來實現(xiàn)事件的“發(fā)布和訂閱”。
通過委托來實現(xiàn)事件處理的過程,通常需要以下4個步驟:
? 定義委托類型,并在發(fā)布者類中定義一個該類型的公有成員。
? 在訂閱者類中定義委托處理方法。
? 訂閱者對象將其事件處理方法鏈接到發(fā)布者對象的委托成員(一個委托類型的引用)上。
? 發(fā)布者對象在特定的情況下“激發(fā)”委托操作,從而自動調用訂閱者對象的委托處理方法。
1.訂閱操作符號“+="和取消訂閱操作符號“-=”
?????????“+=”在這里不是邏輯運算符,而是用于指定響應事件時要調用的方法。這類方法稱為事件處理程序,叫 注冊/訂閱事件,用在操作類名后。
//訂閱符號+=
public static void SubscribeToRing(SchoolRing schoolRing)
{schoolRing.OnBellSound += SchoolJow;
}
????????與之相反功能的“-=”就是取消訂閱、退訂操作符。
//取消訂閱操作符“-=”
public static void CancelSubscribe(SchoolRing schoolRing) ?
{schoolRing.OnBellSound -= SchoolJow;
}
2.示例源碼
// 委托的發(fā)布和訂閱事件namespace Demo
{class Program{static void Main(string[] args){SchoolRing sr = new(); //創(chuàng)建學校鈴聲類的對象Students.SubscribeToRing(sr); //訂閱鈴聲Console.Write("請輸入打鈴參數(shù)(1:表示打上課鈴;2:表示打下課鈴):");sr.Jow(Convert.ToInt32(Console.ReadLine())); //打鈴動作Console.ReadLine();}}public delegate void RingEvent(int ringKind); //聲明一個委托類型/// <summary>/// 定義鈴聲類SchoolRing/// 類中發(fā)布一個委托,定義函數(shù)Jow/// </summary>public class SchoolRing{public RingEvent? OnBellSound; //委托發(fā)布,就好像定義一個實例對象public void Jow(int ringKind) //定義一個公有成員Jow(),打鈴{if (ringKind == 1 || ringKind == 2){Console.Write(ringKind == 1 ? "上課鈴聲響了," : "下課鈴聲響了,");if (OnBellSound != null) //不等于空,說明它已經訂閱了具體的方法(即它已經引用了具體的方法){OnBellSound!(ringKind); //回調OnBellSound委托所訂閱(或引用)的具體方法}}else{Console.WriteLine("這個鈴聲參數(shù)不正確!");}}}/// <summary>/// 定義學生類Students/// 類中定義三個函數(shù)/// </summary>public class Students{public static void SubscribeToRing(SchoolRing schoolRing) //學生們訂閱鈴聲這個委托事件{schoolRing.OnBellSound += SchoolJow;}public static void SchoolJow(int ringKind){if (ringKind == 2) //打了下課鈴{Console.WriteLine("同學們開始課間休息!");}else if (ringKind == 1) //打了上課鈴{Console.WriteLine("同學們開始認真學習!");}}public static void CancelSubscribe(SchoolRing schoolRing) //取消訂閱鈴聲動作{schoolRing.OnBellSound -= SchoolJow;}}
}
二、事件的發(fā)布和訂閱
????????使用事件的目的是:解決安全隱患和不能干涉其他訂閱者。事件的使用方法:C#提供了專門的事件處理機制,以保證事件訂閱的可靠性,其做法是在發(fā)布委托的定義中加上event關鍵字,其他代碼不變。
//事件的使用方法
public event RingEvent OnBellSound; //事件發(fā)布
//不安全的事件訂閱,當不使用event關鍵字時,系統(tǒng)會會忽視威脅的存在
//當使用event關鍵字修飾時,系統(tǒng)會報錯
schoolRing.OnBellSound = SchoolJow; //系統(tǒng)會報錯的,應使用+=
schoolRing.OnBellSound = null; //系統(tǒng)會報錯的,禁止指向null
schoolRing.OnBellSound2 = SchoolJow; //系統(tǒng)會報錯的,事件只能由自身觸發(fā)
三、EventHandler類
????????在事件發(fā)布和訂閱的過程中,定義事件的類型(即委托類型)是一件重復性的工作,為此,.NET類庫中定義了一個EventHandler委托類型,并建議盡量使用該類型作為事件的委托類型。該委托類型的定義為:
public delegate void EventHandler(object sender,EventArgs e);
????????其中,
????????object類型的參數(shù)sender表示引發(fā)事件的對象,由于事件成員只能由類型本身(即事件的發(fā)布者)觸發(fā),因此在觸發(fā)時傳遞給該參數(shù)的值通常為this。例如,可將SchoolRing類的OnBellSound事件定義為EventHandler委托類型,那么觸發(fā)該事件的代碼就是“OnBellSound(this,null);”。
????????EventHandler委托的第二個參數(shù)e表示事件中包含的數(shù)據(jù)。如果發(fā)布者還要向訂閱者傳遞額外的事件數(shù)據(jù),那么就需要定義EventArgs類型的派生類。
// EventHandler類
namespace _09_1
{class Program{/// <summary>/// 操作流程:創(chuàng)建發(fā)布者實例→訂閱該實例→發(fā)布者開始發(fā)布/// </summary>static void Main(string[] args){SchoolRing sr = new(); //創(chuàng)建學校鈴聲類的對象Students.SubscribeToRing(sr); //訂閱鈴聲Console.Write("請輸入打鈴參數(shù)(1:表示打上課鈴;2:表示打下課鈴):");sr.Jow(Convert.ToInt32(Console.ReadLine())); //發(fā)布者觸發(fā)打鈴動作,事件只能由發(fā)布者觸發(fā)Console.ReadLine();}}public delegate void RingEvent(int ringKind); //聲明一個委托類型/// <summary>/// 發(fā)布者/// 校鈴種類及對應的處理方法/// 定義鈴聲類SchoolRing,類中發(fā)布一個委托,定義函數(shù)Jow方法/// </summary>public class SchoolRing{public event EventHandler? OnBellSound; //委托發(fā)布,就好像定義一個實例對象public void Jow(int ringKind) //定義一個公有成員Jow(),打鈴方法{if (ringKind == 1 || ringKind == 2){Console.Write(ringKind == 1 ? "上課鈴聲響了," : "下課鈴聲響了,");if (OnBellSound != null) //不等于空,說明它已經訂閱了具體的方法(即它已經引用了具體的方法){ //為了安全,事件成員只能由類型本身觸發(fā)(this),OnBellSound!(this, new Students.RingEventArgs(ringKind));}}else{Console.WriteLine("這個鈴聲參數(shù)不正確!");}}}/// <summary>/// 訂閱者/// 定義學生類Students/// 類中定義三個函數(shù):訂閱、訂閱方法、取消訂閱/// </summary>public class Students{/// <summary>/// 訂閱/// </summary>public static void SubscribeToRing(SchoolRing schoolRing) //學生們訂閱鈴聲這個委托事件{schoolRing.OnBellSound += SchoolJow;}/// <summary>/// EventHandler委托的第二個參數(shù)e表示事件中包含的數(shù)據(jù)。/// </summary>/// <param name="sender">/// 事件的訂閱者可以通過sender參數(shù)來了解是哪個對象觸發(fā)的事件(這里當然是事件的發(fā)布者),/// 不過在訪問對象時通常要進行強制類型轉換/// </param>/// <param name="e"></param>public static void SchoolJow(object? sender, EventArgs e){if (((RingEventArgs)e).RingKind == 2) //下課鈴,e強制轉化內RingEventArgs類型{Console.WriteLine("同學們開始課間休息!");}else if (((RingEventArgs)e).RingKind == 1) //上課鈴,e強制轉化內RingEventArgs類型{Console.WriteLine("同學們開始認真學習!");}}/// <summary>/// 取消訂閱/// </summary>/// <param name="schoolRing"></param>public static void CancelSubscribe(SchoolRing schoolRing){schoolRing.OnBellSound -= SchoolJow;}/// <summary>/// EventArgs類型的派生類/// 如果發(fā)布者還要向訂閱者傳遞額外的事件數(shù)據(jù),那么就需要定義EventArgs類型的派生類。/// 例如,由于需要把打鈴參數(shù)(1或2)傳入事件中,則可以定義如下的RingEventArgs類:/// </summary>/// <param name="ringKind">/// 鈴聲參數(shù)/// </param>public class RingEventArgs(int ringKind) : EventArgs{//描述鈴聲種類的字段private readonly int ringKind = ringKind;//獲取打鈴參數(shù)public int RingKind {get { return ringKind; }}}}
}
四、Windows事件
????????事件在Windows這樣的圖形界面程序中有著極其廣泛的應用,事件響應是程序與用戶交互的基礎。用戶的絕大多數(shù)操作,都可以觸發(fā)相關的控件事件。關于此類事件,詳見作者發(fā)布的有關Windows窗體應用的文章,此處省略十萬字。