快速理解委托與事件

相信不少初學者對于委托和事件理解的不夠深刻。一直有個疑惑:它們的區(qū)別在哪户誓?什么時候該使用它們取具?本篇文章就幫助你快速理解這對雙胞胎兄弟价认。

委托是就像類一樣,它是一種用戶自定義的數(shù)據(jù)類型顾患。有了類型番捂,必然就有實例(對象),每個委托實例都可以關(guān)聯(lián)多個方法江解,且這些方法必須與委托的類型和返回值相同设预。

而事件本身就是一個對象,它就是狹義的委托犁河,每個事件可用"="關(guān)聯(lián)一個方法,或用"+="關(guān)聯(lián)多個方法鳖枕。

因此魄梯,委托和事件本質(zhì)區(qū)別就是類型和對象的區(qū)別。那么宾符,什么時候使用委托画恰,什么時候用事件呢?簡單來說吸奴,當有多個同類型同返回值的方法等著在特定情況下一起被觸發(fā)允扇,建議使用用委托來管理它們;除此之外,使用事件會更加便捷则奥。


委托使用舉例:

public class Reality

{

? ? //聲明一個委托類型

? ? public delegate void DoSomething(string s);

? ? //創(chuàng)建一個委托實例

? ? public DoSomething doSomething;

? ? //創(chuàng)建委托實例并賦值(關(guān)聯(lián)一個靜態(tài)的考润、與委托同類型和返回值的方法)

? ? DoSomething toDo = new DoSomething(To_do);

? ? DoSomething toStop = new DoSomething(To_stop);

? ?//構(gòu)造方法

? ? public Reality()

? ? {

? ? ? ? //將兩個委托實例合并給另一個委托實例doSomething

? ? ? ? doSomething = toDo;

? ? ? ? doSomething += toStop;

? ? }

? ? private static void To_do(string s)

? ? {

? ? ? ? Debug.Log("he ready to "+s);

? ? }

? ? private static void To_stop(string s)

? ? {

? ? ? ? Debug.Log("he stop to " + s);

? ? }

}

//調(diào)用委托

public class test : MonoBehaviour

{

? ? Reality reality = new Reality();

? ? private void Start()

? ? {

? ? ? ? //使用委托實例,相當于調(diào)用它關(guān)聯(lián)的所有方法

? ? ? ? reality.doSomething("eat");

? ? }

}


說完委托读处,這里再介紹三種經(jīng)常用到的事件:

1.Action系列的泛型事件糊治。它是沒有返回值的事件,最多可以有16參數(shù)罚舱,也可以沒有參數(shù)

示例:

?*聲明事件(可以傳入數(shù)據(jù)類型)?

? ? ? ? public event Action<Transform,Vector3> Drag;? ?

*注冊事件井辜,關(guān)聯(lián)方法

? ? ? ?Drag += new Action<Transform,Vector3>(fun);? ? ? //使用+=或=」苊疲‘+=’能綁定多個方法粥脚,‘=’則指定為一個。

? ? ? ?public void fun(Transform a,Vector3?b) { }? ? ?//方法示例

*調(diào)用事件

? ? ? Drag?.Invoke(transform,Vector3.up);? ? ?//有參數(shù)的事件包个,需要傳參數(shù)


2.Func系列的事件刷允。它具有返回值,最多可以有16個參數(shù)碧囊;它封裝一個具有參數(shù)(也許沒有)但卻返回 TResult 參數(shù)指定的類型值的方法树灶。

示例1:

//聲明事件。最后一個"string"是返回類型,前面兩個都是傳入的參數(shù)類型糯而。

public static Func<int, float, string> func;? ??

//注冊事件

func = new Func<int,float,string>(fun);? ? ??

?//調(diào)用事件??

?string s = func(1,0.5f);? ?

?//目標方法

string fun(int a,float b)? {?return (a + b).ToString(); }? ? ? ? ?


示例2 (在Unity協(xié)程中的運用):

bool IsHit { return false; }? ? ?//返回布爾值的方法

IEnumerator Test()? ?{

? ? ? ? Func<bool> A = IsHit;? ? ? //定義事件A(返回bool值的事件)天通,關(guān)聯(lián)IsHit方法

? ? ? ? Debug.Log("等待A為True。熄驼。像寒。");

? ? ? ? yield return new WaitUntil(A);? ? //等待A為true時繼續(xù)往下執(zhí)行。

}



3.Unity內(nèi)置的事件

上述兩種事件類型都是屬于System名稱空間下谜洽,這里再介紹一個屬于UnityEngine.Events名稱空間下的兩兄弟:UnityAction和UnityEvent萝映。

UnityAction是Unity內(nèi)部實現(xiàn)的事件傳遞系統(tǒng)(屬于函數(shù)指針,將方法傳遞到別的類中執(zhí)行)阐虚,而UnityEvent負責管理UnityAction,它提供了AddListener,RemoveListener等方法蚌卤;UnityAction只可調(diào)用自己实束,而UnityEvent可同時調(diào)用多個UnityAction奥秆。此外,在檢視面板中咸灿,還可以對UnityEvent進行賦值操作构订。

示例:

//聲明實例

? ? public UnityAction<int, string> a1;

? ? public UnityAction<int, string> a2;

? ? public UnityEvent<int, string> myEvents;

//目標方法

? ? public void fun1(int a, string b) { }

? ? public void fun2(int a, string b) { }

//使用"="或"+="關(guān)聯(lián)方法

? ? ? ? a1 = fun1;

? ? ? ? a2 = fun2;

//向UnityEvent實例中添加UnityAction實例

? ? ? ? myEvents.AddListener(a1);

? ? ? ? myEvents.AddListener(a2);

//如果需要移除某個事件,則使用RemoveListener

? ? ? ? myEvents.RemoveListener(a1);

//全部移除

? ? ? ? myEvents.RemoveAllListeners();

?//調(diào)用事件

? ? ? ? a1(1,"a");? ? ?//通過UnityAction直接調(diào)用

? ? ? ? a2(2, "b");

? ? ? ? myEvents.Invoke(3,"c");? ? ?//通過UnityEvent統(tǒng)一調(diào)用


OK,關(guān)于委托和事件的介紹就到此結(jié)束了避矢,各位小伙伴是不是理解更深刻了呢悼瘾?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市审胸,隨后出現(xiàn)的幾起案子亥宿,更是在濱河造成了極大的恐慌,老刑警劉巖砂沛,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烫扼,死亡現(xiàn)場離奇詭異,居然都是意外死亡碍庵,警方通過查閱死者的電腦和手機映企,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來静浴,“玉大人堰氓,你說我怎么就攤上這事∑幌恚” “怎么了豆赏?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長富稻。 經(jīng)常有香客問我掷邦,道長,這世上最難降的妖魔是什么椭赋? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任抚岗,我火速辦了婚禮,結(jié)果婚禮上哪怔,老公的妹妹穿的比我還像新娘宣蔚。我一直安慰自己,他們只是感情好认境,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布胚委。 她就那樣靜靜地躺著,像睡著了一般叉信。 火紅的嫁衣襯著肌膚如雪亩冬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音硅急,去河邊找鬼覆享。 笑死,一個胖子當著我的面吹牛营袜,可吹牛的內(nèi)容都是我干的撒顿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼荚板,長吁一口氣:“原來是場噩夢啊……” “哼凤壁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起跪另,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤拧抖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后罚斗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體徙鱼,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年针姿,在試婚紗的時候發(fā)現(xiàn)自己被綠了袱吆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡距淫,死狀恐怖绞绒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情榕暇,我是刑警寧澤蓬衡,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站彤枢,受9級特大地震影響狰晚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缴啡,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一壁晒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧业栅,春花似錦秒咐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至帮孔,卻和暖如春雷滋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工惊豺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留燎孟,地道東北人禽作。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓尸昧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親旷偿。 傳聞我的和親對象是個殘疾皇子烹俗,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354