喜羊羊與灰太狼之委託與事件

2021-06-08 13:32:18 字數 4416 閱讀 6044

記得我在初學.net的時候對委託和事件這對概念理解的是很模糊的,當時在看書的時候只能理解書中**的邏輯,知道委託和事件怎樣用**具體實現,但對其中的原理理解甚少。這幾天在學習asp.net網頁程式設計的時候,裡面又多次提到了事件、事件引數。於是我決定再重新理解一次委託和事件

為了形象的描述委託和事件實現的過程,我想到了「喜羊羊和灰太狼」的故事。我比較愛看動畫片,尤其是愛看像《喜羊羊與灰太狼》、《蠟筆小新》等這樣既搞笑又弱智的動畫片。沒看過《喜羊羊與灰太狼》的可以趁此機會看一下。

為了描述這個故事,我們首先需要建立兩個類:goat和wolf

//狼類的**

public class wolf

public string name

set

}public void scare() //狼有乙個恐嚇的方法

,小肥羊們快跟我回狼堡吧!",name );

console.writeline(); }}

//山羊類的**

public class goat

public string name

set

}public void run() //羊有乙個逃跑的方法

快跑!" ,name);

console.writeline();}}

在動畫片裡,灰太狼每次看到小羊的時候都是先和小羊聊天、說一些嚇唬小羊的話,然後再上去抓羊,這時候喜羊羊早就想出逃脫的辦法了,怪不得每次灰太狼都抓不到羊,看到羊先和他們扯淡,然後才行動。

不說廢話了,下面我給大家講怎樣用委託和事件實現:狼嚇唬小羊,小羊聽到後撒腿就跑。

首先我們要明白乙個常識:灰太狼再笨也不會自己告訴小羊說我來了,你們快跑吧。所以在wolf類當中不可以出現goat類的物件,也就是說不可以把小羊的run方法寫在狼的scare方法中。wolf和goat雙方不能關聯,那就要通過委託來解決這個問題

委託其實就是對方法的引用,一旦為委託分配了方法,那麼委託就可以像方法一樣使用。委託定義了對方法特徵的抽象,委託和函式一樣可以有引數和返回值,為委託分配的方法的格式要和委託一致,即方法的引數和返回值要和委託一樣。委託可以看做是函式的「類」,為委託分配的函式就是委託的例項。

首先我們定義乙個委託

public delegate void wolfscareeventhandler();
定義乙個沒有引數和返回值的委託,委託的名字是wolfscareeventhandler,委託用關鍵字delegate宣告,可以放在wolf類的裡面,也可以放在類外面,因為委託本身也是一種「特殊的類」

然後我們定義乙個wolfscareeventhandler委託型別的事件wolfscare

public event wolfscareeventhandler wolfscare;
事件用event關鍵字宣告,事件要宣告在wolf類的內部,因為這個事件是屬於wolf類的(我們通常說類有三要素:屬性、事件、方法)

包含wolfscare事件的wolf類**

public class wolf

public string name

set

}//宣告乙個wolfscareeventhandler委託型別的事件

public event wolfscareeventhandler wolfscare;

public void scare()

,小肥羊們快跟我回狼堡吧!",name );

//下面是觸發wolfscare事件的**

if (wolfscare != null)}}

這樣wolf類就具有了事件,而且在狼執行scare方法時事件會被觸發,如果為事件分配了方法,那麼將執行方法。

最關鍵的是要看主程式的**:

有人會說.net中控制項事件過程一般都是帶引數的,像下面這樣:

protected void button1_click(object sender, eventargs e)

這個事件過程帶兩個引數sender和e,分別是object型別和eventargs型別的。sender是指此事件是在哪個物件中被觸發的,在這裡就是button1;e是乙個事件引數,裡面攜帶著一些與此事件相關的資料

那麼我們對「喜羊羊和灰太狼」的**進行改造,讓它的事件也帶引數

先定義乙個事件引數類wolfscareeventargs,讓它繼承eventargs類

public class wolfscareeventargs

set }}

對委託改造:事件過程(即為委託分配的方法)是帶引數的,那麼委託也要帶引數

public delegate void wolfscareeventhandler(object sender,wolfscareeventargs e);
改造後的wolf類

public class wolf

public string name

set

}//宣告乙個wolfscareeventhandler委託型別的事件

public event wolfscareeventhandler wolfscare;

public void scare()

,小肥羊們快跟我回狼堡吧!",name );

console.writeline();

//下面是觸發wolfscare事件的**

if (wolfscare != null)

//重寫tostring方法,這樣sender.tostring()就可以顯示狼的名字了

public override string tostring()

}

goat類的**也要進行改造:

public class goat

public string name

set

}public void run(object sender,wolfscareeventargs e)

來啦,快跑!",e.name ,name); //在這裡可以用引數e的name屬性顯示出哪只狼來了

console.writeline("追我的狼是:"+sender.tostring ()); //這裡可以用sender物件的tostring方法顯示出觸發事件的狼的名字

console.writeline();}}

主程式基本不用變,為了方便演示,我們把狼的名字改為「紅太狼」

static void main(string args)

程式執行的效果:

講到這裡可能有很多人還是覺得上面講的事件和.net中的控制項事件不太一樣,其實他們的原理是一樣的:

當我們雙擊某個控制項時,**編輯器會自動為我們編寫好乙個事件處理過程

protected void button1_click(object sender, eventargs e)

其實這裡的button1_click 就類似於上面講到的goat類的run方法。button1_click過程的背後是事件button1.click,它類似於上面的bigwolf.wolfscare事件。

其實button1_click可以是隨便的乙個名字,比如  fun (object sender, eventargs e),只要你在**中新增如下語句:

button1.click+=new eventhandler(fun);
這樣當button1的click事件被觸發時,就會執行fun方法。你可以為button1.click事件分配任意多的方法,當事件被觸發時,這些方法都會被執行。

你看到的事件過程都是類似於 protected void button1_click(object sender, eventargs e)這樣的,這是因為:當你雙擊某個控制項時,系統自動建立過程protected void button1_click(object sender, eventargs e),並將它分配給事件button1.click. 你也可以把其它控制項的事件過程分配給事件button1.click,如:

protected void textbox1_textchanged(object sender, eventargs e)

button1.click+=new eventhandler(textbox1_textchanged)

這樣單擊button1,textbox1_textchanged事件過程也會被執行。

總之事件過程和一般的函式和方法是一樣的,只不過系統把它分配給了事件,當事件觸發時,執行被分配的事件過程

喜羊羊與灰太狼歌詞

喜羊羊,美羊羊,懶羊羊,沸羊羊,慢羊羊,軟綿綿,紅太狼,灰太狼,別看我只是乙隻羊,綠草因為我變得更香,天空因為為變得更藍,白雲因為我變得柔軟,別看我只是乙隻羊,羊兒的聰明難以想象,天再高心情一樣奔放,每天都追趕太陽,有什麼難題去牽絆我,都不會去心傷,有什麼危險在我面前,都不去慌亂,就算有狼群把我追捕...

做人要做喜羊羊,嫁人要嫁灰太狼

第一條,灰太狼愛老婆勝過愛自己。這可是男人必須要具備的哦。灰太狼每次抓到羊完全可以自己先吃掉,可是他一次都沒有這樣做,總是辛苦地把小羊們送到老婆大人面前,或煮或炸全由老婆說了算。這樣的男人永遠把老婆放在第一位,這可是嫁他的先決條件啊。第二條,灰太狼熱愛勞動。別小看這一條啊,兩口子過日子講究的就是細節...

ZJOI2009 狼與羊的故事 最小割

給定乙個 n times m 方格矩陣,每個格仔可在 0,1,2 中取值。要求在方格的邊上進行劃分,使得任意聯通塊內不同時包含 1 和 2 的格仔。若對方格矩陣的形式感到困惑,我們可以先考慮圖上的形式。假設圖中有節點 w 1 q 1 s 1 s 2 且 w 1 與其它三者間各有一邊,此外 q 1 和...