C#事件的发送方和接收方(订阅方)
生活随笔
收集整理的這篇文章主要介紹了
C#事件的发送方和接收方(订阅方)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
C#事件的發(fā)送方和接收方(訂閱方)
基于Windows的應(yīng)用程序也是基于消息的,Windows使用預(yù)定義消息與應(yīng)用程序通訊。
.NET Framework將Windows消息封裝在事件中,可以把事件作為對象之間的通訊介質(zhì)。
事件發(fā)送方:發(fā)送事件的對象
事件接收方:捕獲事件并對其作出響應(yīng)的對象(處理事件)
在事件通訊機制中,事件發(fā)送方不知道哪個對象將接收到它引發(fā)的事件以及進行什么樣的處理,事件
發(fā)送方不知道誰將是事件接收方,它只是將"事件發(fā)生了"這個消息廣播出去。
在C#中,事件機制是借助委托來實現(xiàn)的。一個事件就相當(dāng)于一個委托實例。
----------------------------------------------------------------------
使用事件:使用事件分為4步,與使用委托有一點小區(qū)別。
1.定義一個委托類型。
這一步與使用委托沒有什么不同,一般都使用 .Net預(yù)定義的委托。
2.定義一個事件名(在事件發(fā)送方中)。
訪問控制符 event 委托類型名 事件名;
3.封裝事件,即將事件處理方法注冊到事件中(事件處理方法定義在事件接收方中)。
事件發(fā)送方.事件名 += new 委托類型名(事件處理方法);
事件名即相當(dāng)于委托實例名,事件處理方法即相當(dāng)于委托實例的關(guān)聯(lián)方法。只不過,在事件機制中,將定義委托實例(使用委托的第二步)分為兩個步驟,分別由事件發(fā)送方和接收方來進行: 定義一個事件名 - 得到一個委托實例名 (事件發(fā)送方) ;封裝該事件 - 得到一個關(guān)聯(lián)方法(將一個事件處理方法與一個事件關(guān)聯(lián)) (事件接收方)。
注:在事件發(fā)送方定義事件名時,可以將事件名聲明為static的,以便事件接收方封裝事件
4.事件發(fā)送方引發(fā)事件,事件接收方的事件處理方法捕獲并處理事件。
引發(fā)事件(相當(dāng)于調(diào)用委托實例)即會導(dǎo)致事件處理方法的執(zhí)行(相當(dāng)于委托實例的關(guān)聯(lián)方法的執(zhí)行)
事件可能由用戶的操作(比如單擊鼠標(biāo))引發(fā),也可能由某些其他的程序邏輯觸發(fā);
--------------------------------------------------------------------
?
using System;
namespace EventExample
{
class ClassReceive //事件接收方
{
[STAThread]
static void Main(string[] args)
{
ClassSend Send = new ClassSend();
//3.封裝事件
Send.CalculateFinished += new MyDelegate(Send_CalculateFinished);
//執(zhí)行下面三行,將導(dǎo)致三次引發(fā)MyClass的CalaculatedFinished事件
Send.Square(2); //調(diào)用事件發(fā)送方的代碼,導(dǎo)致事件被引發(fā)
Send.Cube(2); //調(diào)用事件發(fā)送方的代碼,導(dǎo)致事件被引發(fā)
Send.Double(2); //調(diào)用事件發(fā)送方的代碼,導(dǎo)致事件被引發(fā)
Console.ReadLine();
}
//定義事件處理方法,在事件被引發(fā)后執(zhí)行
private static void Send_CalculateFinished(string msg)
{
Console.WriteLine(msg + "計算完成");
}
}
//1.定義委托,指定返回類型和形參列表。與類定義一樣,同在命名空間下
delegate void MyDelegate(string msg);
class ClassSend //事件發(fā)送方
{
//2.定義事件CalculateFinished,該事件屬于MyClass類
public event MyDelegate CalculateFinished;
//4.執(zhí)行該方法事件將被引發(fā),一般由事件接受方調(diào)用該方法來觸發(fā)事件
public void OnCalculateFinished(string msg)
{
//判斷事件是否為空,事件接受方如果定義了事件的處理方法,則不為null
if (CalculateFinished != null)
{
//如果事件為空就觸發(fā)事件,將導(dǎo)致一個空引用異常
CalculateFinished(msg);
//就是這一句引發(fā)事件,即: 事件名(形參列表);
//此方法的形參列表已經(jīng)由與事件相關(guān)的委托指定了
}
}
public void Square(float x)
{
float result = x * x;
Console.WriteLine("{0}的平方等于:{1}", x, result);
//執(zhí)行事件引發(fā)方法,將導(dǎo)致事件被引發(fā)
OnCalculateFinished("平方");
}
public void Cube(float x)
{
float result = x * x * x;
Console.WriteLine("{0}的立方等于:{1}", x, result);
//執(zhí)行事件引發(fā)方法,將導(dǎo)致事件被引發(fā)
OnCalculateFinished("立方");
}
public void Double(float x)
{
float result = 2 * x;
Console.WriteLine("{0}的倍數(shù)等于:{1}", x, result);
//執(zhí)行事件引發(fā)方法,將導(dǎo)致事件被引發(fā)
OnCalculateFinished("倍數(shù)");
}
}
}
--------------------------------------------------------------------
事件是多點委托,對事件只能使用 += 和 -= 運算,= 運算對于事件是無效的。
.NET 提供了一個預(yù)定義的用于事件的委托類型 - EventHandler
public delegate void EventHandler(Object sender,EventArgs e);
參數(shù)sender是引發(fā)事件的事件發(fā)送方對象,e是事件的有關(guān)數(shù)據(jù)
在定義事件時,可以不必自定義委托類型,直接使用這個預(yù)定義的事件委托類型就可以了。
自定義事件時,應(yīng)該遵守一些命名規(guī)范:
使用動詞命名事件,最好帶上現(xiàn)在、進行或完成時態(tài)來描述事件的觸發(fā)時效;
事件的委托類型的命名一般以"EventHandler"為后綴,事件參數(shù)類名稱以"EventArgs"為后綴;
總是使用 sender 和 e 來命名事件中的兩個參數(shù);
事件發(fā)送方中,引發(fā)事件的方法的命名一般用 On + 事件名 eg:OnCalaculateFinished(string msg);
在事件發(fā)送方類中,定義引發(fā)事件的方法(其中包含調(diào)用事件的語句)時,必須先判斷事件是否為空,因為事件是在接收方中封裝的(定義事件處理方法),事件發(fā)送方無法知曉是否存在有事件處理方法(發(fā)送方不知道接收方的存在),所以在事件發(fā)送方中引發(fā)事件的代碼處,必須先判斷事件是否為空。另外,往往是在事件接收方中,調(diào)用了事件發(fā)送方的代碼,然后導(dǎo)致事件被引發(fā),因而,在事件接收方中,封裝事件的代碼應(yīng)該先于調(diào)用事件發(fā)送方的代碼執(zhí)行。
轉(zhuǎn)載于:https://www.cnblogs.com/Holmes-Jin/archive/2012/03/16/2399721.html
總結(jié)
以上是生活随笔為你收集整理的C#事件的发送方和接收方(订阅方)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个女生很酷的qq网名
- 下一篇: 新大洲本田裂行125踏板车卖多少钱