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\#이벤트 관리자 가 모든 감청 을 어떻게 비 우 는 지 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C\#이벤트 관리자 가 모든 감청 내용 을 비 웠 습 니 다.우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기