您好,登錄后才能下訂單哦!
這篇文章主要講解了C#事件管理器清空所有監聽的實現方法,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。
C#事件使用+= -=使用起來是很方便的,但是卻不能整體清空所有事件。比如一個常見的操作,打開界面注冊監聽事件,關閉界面需要把所有的事件清空了,這要在寫一堆-=操作,如果漏清空的話肯定會造成隱患,如果在lua里這個很容易,但是C#卻不行。所以我想了個辦法,對Action和Func進行一次包裝,就可以解決這個問題了。
這里我只封裝了兩個參數,大家可以繼續拓展新的參數,我在項目里一共拓展了5個參數,完全夠用了。
using System; using System.Collections.Generic; public class ActionManager { Dictionary<object, object> m_Actions = new Dictionary<object, object>(); public NewAction RegAction(NewAction newAction , Action action) { newAction += action; m_Actions[newAction] = action; return newAction; } public NewAction<T1> RegAction<T1>(NewAction<T1> newAction, Action<T1> action) { newAction += action; m_Actions[newAction] = action; return newAction; } public NewFunc<T1> RegAction<T1>(NewFunc<T1> newAction, Func<T1> action) { newAction += action; m_Actions[newAction] = action; return newAction; } public NewFunc<T1,T2> RegAction<T1, T2>(NewFunc<T1, T2> newAction, Func<T1, T2> action) { newAction += action; m_Actions[newAction] = action; return newAction; } public void Clear() { foreach (var act in m_Actions) { ((IAction)act.Key).Dispose(act.Value); } } } public interface IAction { void Dispose(object obj); } public class NewAction : IAction { Action action; public void Dispose(object obj) { if(obj is Action act) action -= act; } public void Invoke() { action?.Invoke(); } public static NewAction operator +(NewAction a, Action b) { a.action -= b; a.action += b; return a; } public static NewAction operator -(NewAction a, Action b) { a.action -= b; return a; } } public class NewAction<T1> : IAction { Action<T1> action; public void Dispose(object obj) { if (obj is Action<T1> act) action -= act; } public void Invoke(T1 t1) { action?.Invoke(t1); } public static NewAction<T1> operator +(NewAction<T1> a, Action<T1> b) { a.action -= b; a.action += b; return a; } public static NewAction<T1> operator -(NewAction<T1> a, Action<T1> b) { a.action -= b; return a; } } public class NewFunc<T1> : IAction { Func<T1> func; public void Dispose(object obj) { if (obj is Func<T1> act) func -= act; } public T1 Invoke() { return func != null ? func.Invoke() : default(T1); } public static NewFunc<T1> operator +(NewFunc<T1> a, Func<T1> b) { a.func -= b; a.func += b; return a; } public static NewFunc<T1> operator -(NewFunc<T1> a, Func<T1> b) { a.func -= b; return a; } } public class NewFunc<T1, T2> : IAction { Func<T1, T2> func; public void Dispose(object obj) { if (obj is Func<T1, T2> act) func -= act; } public T2 Invoke(T1 t1) { return func != null ? func.Invoke(t1) : default(T2); } public static NewFunc<T1, T2> operator +(NewFunc<T1, T2> a, Func<T1, T2> b) { a.func -= b; a.func += b; return a; } public static NewFunc<T1, T2> operator -(NewFunc<T1, T2> a, Func<T1, T2> b) { a.func -= b; return a; } }
使用方法如下,注意我們自己封裝的事件必須要new。
using UnityEngine; public class Main : MonoBehaviour { NewAction<string> MyAction = new NewAction<string>();//事件需要new NewFunc<string,int> MyFunc = new NewFunc<string,int>();//事件需要new ActionManager m_ActionManager = new ActionManager(); public void MyFunction(string str) { Debug.Log(" MyFunction " + str); } public int MyFunction1(string str) { Debug.Log(" MyFunction1 " + str); return 1; } private void OnGUI() { if (GUILayout.Button("<size=50>注冊事件</size>")) { m_ActionManager.RegAction(MyAction, MyFunction); m_ActionManager.RegAction(MyFunc, MyFunction1); } if (GUILayout.Button("<size=50>發事件</size>")) { MyAction.Invoke("參數1"); MyFunc.Invoke("參數2"); } if (GUILayout.Button("<size=50>清空</size>")) { m_ActionManager.Clear(); } } }
事件管理器可以放在UI或者模塊的基類中,這樣子類在寫的時候可以直接this.RegAction注冊事件,關閉界面或者卸載模塊的時候由父類調用Clear方法,這樣業務邏輯就不需要在寫-=這樣的代碼了。
看完上述內容,是不是對C#事件管理器清空所有監聽的實現方法有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。