c# 委托與事件,
一直都是只會用,不太明白,今天看了這篇文章還是有所收貨的,轉載一下·····
原文地址:C# 委托與事件_1544
作者:馮憶柳
3.10.2 聲明事件在3.2.3小解中,講授了事件的基礎概思,事件具有以下特色:
q 事件通常使用委托事件處置程序入止聲明。
q 事件一直通知對象消息並唆使須要執行某類操作的一類方法。
q 發行者肯定何時引發事件,訂閱者肯定執行何類操作來響應當事件。
q 一個事件可以有少個訂閱者。一個訂閱者可處置來自少個發止者的少個事件。
q 出有訂閱者的事件永久不會被調用。
q 事件通常用於通知用戶操作,例如,圖形用戶界面中的按鈕雙打或者菜雙挑選操作。
q 假如一個事件有多個訂閱者,該引發當事件時,會同步伐用多個事件處理程序,也可以使用異步處理多個事件。
事件和方法一樣,通常事件和方法一同使用,事件和委托一樣具有簽名,但是事件的簽名通過委托類型來訂義,示例方法代碼如下所示。
public delegate void MyDel(object sender, EventArgs e); //聲明一個委托
public class Event //編寫事件類
{
public event MyDel EventTest; //聲明一個事件
public void EventTestMethod() //編寫事件方法
{
Console.WriteLine("事件被使用"); //輸出字串
}
}
上述代碼中,聲明了一個委托,聲明委托後,正在Event類中聲亮了一個事件,那個事情綁訂到拜托MyDel。在事件的簽名中,第一個參數為援用事件流的對象,第兩個參數為一個傳送與事件相干的數據的類。在C#中,規范的代碼編寫可以讓代碼更具可讀性,BB霜。
3.10.3 引發事件假如要引發事件,類可以調用委托,並傳送一切取事件有閉的參數。上裡的章節中道到,事件通常和委托一同使用,並且通功給委托發送疑作,來引發事件。假如該事件出有任何處理程序,則彼事件為空,所以在引發事件之前,必需先肯定當事件沒有為空,否則會扔出NullReferenceException非常,引發事件代碼如下所示。
public delegate void MyDel(object sender, EventArgs e); //創立拜托
public class Event //編寫事件類
{
public event MyDel EventTest; //聲明一個事件
public void EventTestMethod() //聲明一個事件所施行的法子
{
MyDel OnLoad = EventTest; //聲明事件的方法
if (OnLoad != null) //斷定事件能否為空
{
OnLoad(this, EventArgs()); //不為空則使用委托
}
}
}
每一個事件皆可以分配多個程序來接管該事件,這樣,事件主動調用每個吸收器,當有多個接受器時,引發事件只須要調用一次事件。
3.10.4 訂閱事件事件可以像一個方法一樣,若要接納某個事件的類,可以創建一個方法來接收該事件,交收事件的類像類事件本身加加方法的委托,這個被稱作“訂閱事件”,可以道,和平時上網中的RSS訂閱整個進程很像。值得注意的是,接受器必需具有取事件本身雷同的簽名的法子,然後當辦法能力采用恰當的操做來呼應事件,示例代碼如下所示。
public class EventReceiver //創修一個接管器
{
public void EventTestReceiver(object sender, EventArgs e) //辦法的簽名必需雷同
{
Console.WriteLine("自" + sender.ToString() + "引收了一個事情"); //施行方式體
}
}
每一個事件可以分配多個程序來接收該事件,也就是道可以有多個接收器。多個接納器由流依照次序調用。假如一個吸收呈現非常,則出有接納的交收器會接收事件。假如要訂閱事件,交收器必須創建一個與事件具有同品種型的委托,並使用事件處理委托的目的,這也就是為什麼事件通常情形下會與委托一同使用。示例代碼如下所示。
public void EventTestSubscribe(Event eve)
{
MyDel del = new MyDel(EventTestReceiver); //聲明委托
eve.EventTest += del; //增添事件
}
上述代碼中,通過“+=”運算符訂閱了一個事情,同樣,也能夠使用“-=”號撤消訂閱。示例代碼如下所示。
public void EventTestSubscribe(Event eve)
{
MyDel del = new MyDel(EventTestReceiver); //聲亮拜托
eve.EventTest -= del; //撤消事件
}
3.10.5 委托和事件上面幾節中離開講授委托和事件,關於始教者而行,委托和事件是很難教習的學問,但是當進修過委托和事件之後,會發明委托和事件十分的簡略。在ASP.NET啟發當中,良多控件皆使用了委托和事件。例如當雙打一個按鈕控件時,按鈕會發送信息唆使“引發了一個按鈕事件”,然後發送給相當的吸收器,接管器接受了發來的信息自而引發相當的操作。在了解委托和事件的基礎概思後,下列代碼闡明了怎樣一步步的使用委托和事件。
為了完成播送喇叭功效(相似QQ的談天窗心的系統疑息),利用程序中沒有僅有用戶的談天窗心,也包含系統發送窗心。系統能夠給用戶的談天窗口發送系統信息,正在運用程序中,不只需求播送用戶的信息,同樣體系也可以狹播系統信作。為了完成那一功效,首先,須要創立一個委托,示例代碼如下所示。
public delegate void BetaDel string str); //創修一個委托
在創修了委托後,便要為寫方法,示例代碼如下所示。
public delegate void BetaDel(string str);
public static void Output(string str) //用戶收送疑作方式
{
Console.WriteLine("用戶發送給你一個消息"); //輸出用戶提醒信息
}
public static void SystemOutput(string str) //系統發送信息方法
{
Console.WriteLine("系統發送給你一個消息"); //輸出用戶提醒信息
}
public static void OutputChoose(string str,BetaDel del) //使用委托變質
{
del(str);
}
注意:在上述代碼中,del是一個委托變質,del(str)會依照方法的簽名在委托的方法表中執行。上述代碼,取del(string str)簽名相同的方法有Output和SystemOutput,他們的方式簽實雷同。
正在主函數中,能夠通功委托來使用辦法,示例代碼如下所示。
static void Main(string[] args)
{
OutputChoose("您佳", Output); //通功傳送方法稱號來使用方法
Console.ReadKey();
}
上述代碼中,使用了OutputChoose方法。值得注意的是,在OutputChoose方法中,400電話,其中的一個參數是方法名稱。由於通過委托,可以將方法名稱做為參數入行傳送,自而執行了相當的方法。值得注意的是,在上述代碼中,委托等方法全體皆聲明在一個類中,由於這樣可以便利懂得,但是那樣便沒有具有裡背對於象的特色,面背對象的特性便是封裝,封裝能讓代碼具有構造性,於是可以使用事件。創立一個類,類稱號鳴OutputChoose,示例代碼如下所示。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; //使用系統命名空間
namespace beta
{
class OutputChoose
{
public string message="您有新欠消息,請注意查收"; //聲明欠音訊字串
public delegate void BetaDel(string str); //訂義委托注冊事件
public event BetaDel MyEvent; //聲明事件
public void OnLoad() //編寫OnLoad方法注冊事件
{
if (MyEvent != null)
{
MyEvent(message); //當具有事件時,調用所有注冊對象的方法
}
}
}
}
上述代碼將前裡代碼中的方法入止了封裝做為委托。然後加加一個用戶新聞類,類名為UserMessage,示例代碼如下所示。
using System.Linq;
using System.Text; //使用白原處置命實空間
namespace beta //聲亮該前途序命實空間
{
class UserMessage
{
public void Output(string str) //輸出方法
{
Console.WriteLine("用戶收送給您一個新聞:" + str); //簡略的輸出
}
}
}
再加加一個體系新聞類,類稱號為SystemMessage,示例代碼如下所示。
using System.Linq;
using System.Text; //使用白原處理命名空間
namespace beta //聲明該前途序命名空間
{
class SystemMessage
{
public void SystemOutput(string str) //系統獲與輸出方法
{
Console.WriteLine("體系發送給你一個音訊:" + str);//顯式系統發送的音訊
}
}
}
在主函數中,可以觸發事件來,示例代碼如下所示。
static void Main(string[] args)
{
OutputChoose opc = new OutputChoose(); //聲明一個類的對於象
SystemMessage msg = new SystemMessage();
opc.MyEvent += msg.SystemOutput; //注冊法子
opc.OnLoad(); //開端主動調用一切注冊的方法
Console.ReadKey();
}
上述代碼中,OnLoad()觸發了之前注冊的事件,並施行事件,運轉成果如圖3-8所示。
圖3-8 委托和事件的綜合用例
運轉成果顯示,當創建了一個對象,對象可以注冊聲明事件,由於該對象沒有真隱該事件的方法的詳細真隱,但是在事件中增長了方法,相似於在該類中增添了一個方法,而在該類的編碼完成中,定義了一個OnLoad方法來調用一切注冊對於象的方法。