日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

大白话系列之C#委托与事件讲解(三)

發(fā)布時間:2025/3/21 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大白话系列之C#委托与事件讲解(三) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天我接著上面的3篇文章來講一下,為什么我們在日常的編程活動中遇到這么多sender,EventArgs e 參數(shù):
protected void Page_Load(object sender, EventArgs e)
{

}

protected void btnSearch_Click(object sender, ImageClickEventArgs e)
{

}

protected void grdBill_RowDataBound(object sender, GridViewRowEventArgs e)
{
???????????
}
那他們到底表示什么呢?

在回答上面的問題之前,我們先搞懂 .Net Framework的編碼規(guī)范:

一、委托類型的名稱都應(yīng)該以EventHandler結(jié)束。?
二、委托的原型定義:有一個void返回值,并接受兩個輸入?yún)?shù):一個Object 類型,一個 EventArgs類型(或繼承自EventArgs)。?
三、事件的命名為 委托去掉 EventHandler之后剩余的部分。?
四、繼承自EventArgs的類型應(yīng)該以EventArgs結(jié)尾。

這就是微軟編碼的規(guī)范,當(dāng)然這不僅僅是規(guī)則,而是在這種規(guī)則下使程序有更大的靈活性,那我們就繼續(xù)重構(gòu)第三講的例子,讓他符合微軟的規(guī)范。

代碼

????//所有訂閱者【Subscriber】感興趣的對象,也就是e,都要繼承微軟的EventArgs
????
//本例中訂閱者【也稱觀察者】MrMing,MrZhang他們感興趣的e對象,就是雜志【magazine】
????public?class?PubEventArgs?:?EventArgs
????{
????????
public?readonly?string?magazineName;
????????
public?PubEventArgs()
????????{
?
????????}
????????
public?PubEventArgs?(string?magazineName)
????????{
???????????
this.magazineName?=?magazineName;
????????}
????}

????
//發(fā)布者(Publiser)
????public?class?Publisher
????{
????????
//聲明一個出版的委托
????????
//這里多了一個參數(shù)sender,它所代表的就是Subject,也就是監(jiān)視對象,本例中就是Publisher
????????public?delegate?void?PublishEventHander(object?sender?,PubEventArgs?e);
????????
//在委托的機制下我們建立以個出版事件
????????public?event?PublishEventHander?Publish;

????????
//聲明一個可重寫的OnPublish的保護(hù)函數(shù)
????????protected?virtual?void?OnPublish(PubEventArgs?e)
????????{
????????????
if?(Publish?!=?null)
????????????{
????????????????
//Sender?=?this,也就是Publisher
????????????????this.Publish(this,?e);
????????????}
????????}

????????
//事件必須要在方法里去觸發(fā)
????????public?void?issue(string?magazineName)
????????{
????????????OnPublish(
new?PubEventArgs(magazineName));
????????}
????}

????
//Subscriber?訂閱者
????public?class?MrMing
????{
????????
//對事件感興趣的事情
????????public?static?void?Receive(object?sender,PubEventArgs?e)
????????{
????????????Console.WriteLine(
"嘎嘎,我已經(jīng)收到最新一期的《"+e.magazineName+"》啦!!");
????????}
????}

????
public?class?MrZhang
????{
????????
//對事件感興趣的事情
????????public?static?void?Receive(object?sender,?PubEventArgs?e)
????????{
????????????Console.WriteLine(
"幼稚,這么大了,還看《火影忍者》,SB小明!");
????????????Console.WriteLine(
"這個我定的《"+e.magazineName+"》,哇哈哈!");
????????}
????}

????
class?Story
????{
????????
public?static?void?Main(string[]?args)
????????{
????????????
//實例化一個出版社
????????????Publisher?publisher?=?new?Publisher();

????????????Console.Write(
"請輸入要發(fā)行的雜志:");
????????????
string?name?=?Console.ReadLine();

????????????
if?(name?==?"火影忍者")
????????????{
????????????????
//給這個出火影忍者的事件注冊感興趣的訂閱者,此例中是小明
????????????????publisher.Publish?+=?new?Publisher.PublishEventHander(MrMing.Receive);
????????????????
//發(fā)布者在這里觸發(fā)出版火影忍者的事件
????????????????publisher.issue("火影忍者");
????????????}
????????????
else
????????????{
????????????????
//給這個出火影忍者的事件注冊感興趣的訂閱者,此例中是小明[另一種事件注冊方式]
????????????????publisher.Publish?+=?MrZhang.Receive;
????????????????publisher.issue(
"環(huán)球日報");
????????????}
????????????Console.ReadKey();
????????}
????}

?

輸入火影忍者后,觸發(fā)小明訂閱的事件

顯示

通過例子我再做一次說明,其實我們不用把Sender,e想的過于可怕

一、委托聲明原型中的Object類型的參數(shù)代表了Subject,也就是監(jiān)視對象,在本例中是 Publisher(出版社)。。?
二、EventArgs 對象包含了Observer所感興趣的數(shù)據(jù),在本例中是雜志。

?

?

?大家先休息休息,讓大腦放松放松,先讓我們看句名人名言:

?很多事情就像看A片,看的人覺得很爽,做的人未必!

?“中國人的勵志和國外的勵志存在非常大的不同,中國的勵志比較鼓勵人立下大志愿,臥薪嘗膽,有朝一日成富成貴。而國外的勵志比較鼓勵人勇敢面對現(xiàn)實生活,面對普通人的困境,雖然結(jié)果也是成富成貴,但起點不一樣,相對來說,我覺得后者在操作上更現(xiàn)實,而前者則需要用999個失敗者來堆砌一個成功者的故事。”

?

好了,我們接著講我們的委托與事件,其實如果大家對設(shè)計模式精通的話,其實他們關(guān)聯(lián)的是觀察者(Observer)模式,這里我就不再描述什么是觀察者模式了,只是簡單講一下他們的關(guān)聯(lián):

在C#的event中,委托充當(dāng)了抽象的Observer接口,而提供事件的對象充當(dāng)了目標(biāo)對象。委托是比抽象Observer接口更為松耦合的設(shè)計。

如果看不懂的話也沒關(guān)系,當(dāng)大家OO達(dá)到一定程度了,自然而然就會明白。

?

最后我們來看一個我們?nèi)粘W钭畛S玫挠^察者模式:

場景:當(dāng)我們用信用卡刷完錢的時候,我們就會接收到手機短信,或者是電子郵件,其實這就是Observer pattern

?

代碼

??? //---本例場景為當(dāng)用戶從銀行賬號里取出錢后,馬上通知電子郵件和發(fā)手機短信---
????
//本例中的訂閱者,也就是觀察者是電子郵件與手機
????
//發(fā)布者,也就是被監(jiān)視對象是銀行賬號


????
//Obverser電子郵件,手機關(guān)心的對象e?,分別是郵件地址、手機號碼、取款金額
????public?class?UserEventArgs?:?EventArgs
????{
????????
public?readonly?string?emailAddress;
????????
public?readonly?string?mobilePhone;
????????
public?readonly?string?amount;
????????
public?UserEventArgs(string?emailAddress,?string?mobilePhone,string?amount)
????????{
????????????
this.emailAddress?=?emailAddress;
????????????
this.mobilePhone?=?mobilePhone;
????????????
this.amount?=?amount;
????????}
????}

????
//發(fā)布者,也就是被監(jiān)視的對象-銀行賬號
????class?BankAccount
????{
????????
//聲明一個處理銀行交易的委托
????????public?delegate?void?ProcessTranEventHandler(object?sender,?UserEventArgs?e);
????????
//聲明一個事件
????????public?event?ProcessTranEventHandler?ProcessTran;

????????
protected?virtual?void?OnProcessTran(UserEventArgs?e)
????????{
????????????
if?(ProcessTran?!=?null)
????????????{
????????????????ProcessTran(
this,?e);
????????????}
????????}

????????
public?void?Prcess(UserEventArgs?e)
????????{
????????????OnProcessTran(e);
????????}
????}

????
//觀察者Email
????class?Email
????{
????????
public?static?void?SendEmail(object?sender,?UserEventArgs?e)
????????{
????????????Console.WriteLine(
"向用戶郵箱"?+?e.emailAddress?+?"發(fā)送郵件:您在"+System.DateTime.Now.ToString()+"取款金額為"+e.amount);
????????}
????}

????
//觀察者手機
????class?Mobile
????{
????????
public?static?void?SendNotification(object?sender,?UserEventArgs?e)
????????{
????????????Console.WriteLine(
"向用戶手機"?+?e.mobilePhone?+?"發(fā)送短信:您在"?+?System.DateTime.Now.ToString()?+?"取款金額為"?+?e.amount);
????????}
????}

????
//訂閱系統(tǒng),實現(xiàn)銀行系統(tǒng)訂閱幾個Observer,實現(xiàn)與客戶端的松耦合
????class?SubscribSystem
????{
????????
public?SubscribSystem()
????????{
?
????????}

????????
public?SubscribSystem(BankAccount?bankAccount,?UserEventArgs?e)
????????{
????????????
//現(xiàn)在我們在銀行賬戶訂閱2個,分別是電子郵件和手機短信
????????????bankAccount.ProcessTran?+=?new?BankAccount.ProcessTranEventHandler(Email.SendEmail);
????????????bankAccount.ProcessTran?
+=?new?BankAccount.ProcessTranEventHandler(Mobile.SendNotification);
????????????bankAccount.Prcess(e);
????????}
????}

????
class?Client
????{
????????
public?static?void?Main(string[]?args)
????????{
????????????Console.Write(
"請輸入您要取款的金額:");
????????????
string?amount?=?Console.ReadLine();
????????????Console.WriteLine(
"交易成功,請取磁卡。");
????????????
//初始化e
????????????UserEventArgs?user?=?new?UserEventArgs("jinjiangbo2008@163.com",?"18868789776",amount);
????????????
//初始化訂閱系統(tǒng)
????????????SubscribSystem?subject?=?new?SubscribSystem(new?BankAccount(),?user);
????????????Console.ReadKey();
????????}
????}

?

?

?控制臺

?

網(wǎng)上還有個熱水器燒水的OBSERVER PATTERN 也是蠻經(jīng)典的,大家可以看看。

from:?https://www.cnblogs.com/wudiwushen/archive/2010/04/21/1717378.html

總結(jié)

以上是生活随笔為你收集整理的大白话系列之C#委托与事件讲解(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。