C#事件管理器如何清空所有監(jiān)聽詳解
C#事件使用+= -=使用起來是很方便的,但是卻不能整體清空所有事件。比如一個常見的操作,打開界面注冊監(jiān)聽事件,關閉界面需要把所有的事件清空了,這要在寫一堆-=操作,如果漏清空的話肯定會造成隱患,如果在lua里這個很容易,但是C#卻不行。所以我想了個辦法,對Action和Func進行一次包裝,就可以解決這個問題了。
這里我只封裝了兩個參數,大家可以繼續(xù)拓展新的參數,我在項目里一共拓展了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>發(fā)事件</size>")) { MyAction.Invoke("參數1"); MyFunc.Invoke("參數2"); } if (GUILayout.Button("<size=50>清空</size>")) { m_ActionManager.Clear(); } } }
事件管理器可以放在UI或者模塊的基類中,這樣子類在寫的時候可以直接this.RegAction注冊事件,關閉界面或者卸載模塊的時候由父類調用Clear方法,這樣業(yè)務邏輯就不需要在寫-=這樣的代碼了。
總結
到此這篇關于C#事件管理器如何清空所有監(jiān)聽的文章就介紹到這了,更多相關C#事件管理器清空所有監(jiān)聽內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
深入C# winform清除由GDI繪制出來的所有線條或圖形的解決方法
本篇文章是對在C#中使用winform清除由GDI繪制出來的所有線條或圖形的方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05