【unity】使用委托调用实现低耦合

一、委托的官方文档

C# 中的委托和事件简介 - C# | Microsoft Learn

委托是对具有相同返回类型和参数的方法进行封装,本质上委托也是类,可以跟类一样申明。

委托可以将函数当成参数进行传递。

也可以把委托看成是函数的指针:整数对应使用整数变量指向

二、C#中委托的使用

1、委托的申明
//无参数无返回值
public delegate void RegesterDelegate1();

//有参数无返回值
public delegate void RegesterDelegate2(string str);

//有参数有返回值
public delegate string RegesterDelegate3();

//无参数有返回值
public delegate void RegesterDelegate4(string str);

如果代码需要执行操作,但不知道操作细节,一般可以使用委托。

例如:Thread类之所以知道要在一个新线程里运行申明,唯一的原因就是在启动新线程的时候,向其提供了一个ThreadStart或ParameterizedThreadStart委托实例

Thread newTh = new Thread(Test);
newTh.Start();
public Thread(ThreadStart start);
public delegate void ThreadStart();
//其中,ThreadStart是一个无参无返回值的委托

static void Test()
{
     Console.WriteLine("thread test");   
}

2、委托的调用

申明委托之后要进行实例化,实例化之后才可以进行调用。

实例化的方式:

方式1:使用new创建委托实例

   #传入符合委托返回类型和参数列表的方法 可完成委托的实例化
   ShowDelegate showDelegate = new ShowDelegate(test.Show);
方式2:使用赋值的方式

   ShowDelegate showDelegate = test.Show;
方式3:匿名委托,要求匿名委托和当前的委托具有同样的返回类型和参数列表

   ShowDelegate showDelegate = delegate ()
   {
         Console.WriteLine("匿名委托");
   };
方式4:Lambda表达式

   ShowDelegate2 showDelegate2 = (string s, int v) => { Console.WriteLine($"{s}&{v}"); };
   showDelegate2("s",2);
调用委托:

1、直接调用;

2、使用invoke();

unity里的综合使用:

使用委托的方式实现一个方法管理脚本,实现脚本间的低耦合

public class MethodsManager : MonoBehaviourSingleton<MethodsManager >//单例
{
     //无参数
    public delegate void callBack();
    Dictionary<string, callBack> AllcallBackfunction = new Dictionary<string, callBack>();
    //一个参数 
    public delegate void callBack_one<T>(T t);
    Dictionary<string,callBack_one<System.Action>> AllcallBackfunction_Action=new Dictionary<string, callBack_one<System.Action>>();

#region 注册方法
    /// <summary>
    /// 重载注册方法 无参数
    /// </summary>
    /// <param name="A"></param>
    public void AttachMethod(callBack A)
    {
        if (!AllcallBackfunction.ContainsKey(A.Method.Name))
        {
            Instance.AllcallBackfunction.Add(A.Method.Name, A);
        }
        else
        {
            Debug.Log(A.Method.Name + " 方法存在,重命名");
        }
    }

    public void AttachMethod(callBack_one<System.Action> A)
    {
        if (!AllcallBackfunction_Action.ContainsKey(A.Method.Name))
        {
            Instance.AllcallBackfunction_Action.Add(A.Method.Name, A);
        }
        else
        {
            Debug.Log(A.Method.Name + " 方法存在,重命名");
        }
    }
    #endregion

    #region 执行方法
    /// <summary>
    /// 无参数无返回值调用方法
    /// </summary>
    /// <param name="key">方法名</param>
    public void InvokeMethod(string key)
    {
        if (AllcallBackfunction.ContainsKey(key))
        {
            AllcallBackfunction[key].Invoke();
        }
        else
        {
            Debug.Log(key + " 方法不存在,重新注册");
        }
    }

    public void InvokeMethod(string key,System.Action parameter)
    {
        if (AllcallBackfunction_Action.ContainsKey(key))
        {
            AllcallBackfunction_Action[key].Invoke(parameter);
        }
        else
        {
            Debug.Log(key + " 方法不存在,重新注册");
        }
    }
    #endregion

}

调用示例:

public class Test : MonoBehaviour
{
    void Start()
    {
        //Regester private method in ManagerMethods
        MethodsManager.Instance.AttachMethod(P_Method);
    }
    //private method
    private void P_Method()
    {
        Debug.Log("我是P_Method");
    }
}

除了方法,还有数据的耦合性,如果两个脚本,脚本A想要访问脚本B的输出数据,一定要进行隔离:


public class DataManager : Singleton<DataManager>
{
    public int data1{get;set;}
    ...
}

DataManager是一个单例,B的输出数据存储到此处,A只要使用DataManager.Instance.data1就能获取到。

这样的写法可以有效的管理功能方法和数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值