Unity3D 委托的使用


函数回调机制——委托

using UnityEngine;
using System.Collections;

public class DelegateScripts:MonoBehaviour
{
   //声明一个委托类型,它的实例引用一个方法
   internal delegate void MyDelegate(int num);
   MyDelegate myDelegate;

   void Start()
   {
       //委托类型 MyDelegate的实例myDelegate引用的方法是
       //PrintNum
       myDelegate=PrintNum;
       myDelegate(50);
       //委托类型 MyDelegate的实例myDelegate引用的方法是
       //DoubleNum
       myDelegate=DoubleNum;
       myDelegate(50);

   }

   void PrintNum(int num)
   {
       Debug.Log("Print Num: "+num);

   }
   void DoubleNum(int num)
   {
        Debug.Log("Double Num:"+num*2);
   }
}

在最开始没可以看到internal委托类型MyDelegate的声明。委托要确定一个回调方法签名,包括参数以及返回类型等。在本例中MyDelegate的回调方法的参数类型是int,返回类型为void。在“myDelegate=PrintNum;”这句话中使用了C#2为委托提供的方法组转换。在使用方法组转换时,隐式转换将一个方法组转换为具有兼容签名的任意委托类型。代码演示如下:

public class DelegateScript:MonoBehaviour
{
    //声明一个委托类型,它的实例引用一个方法
    delegate void MyDelegate(int num);
    //声明一个委托类型,它的实例引用一个方法
    delegate void Mydelegate2(int num1, int num2);

    MyDelegate myDelegate;
    Mydelegate2 myDelegate2;

    void Start()
    {
        myDelegate = PrintNum;
        myDelegate(50);

        myDelegate2 = PrintNum;//重载版本
        myDelegate2(50,50);
    }

    void PrintNum(int num)
    {
        Debug.Log("Print Num:" + num);
    }
    void PrintNum(int num1,int num2)
    {
        int result = num1 + num2;
        Debug.Log("result num is:" + result);
    }
}

委托的协变性和逆变性
协变性是指方法的返回类型可以是从委托的返回类型派生的,也就是说协变性描述的是委托返回类型。逆变性则是指方法获取的参数的类型可以是委托的参数的类型的基类,换言之逆变性描述的是委托的参数类型。举例如下:
我们在项目中存在的基础单位类BaseUnitClass、士兵类SoldierClass以及英雄类HeroClass,其中士兵类和英雄类派生自基础单位类
那么可以定义一个委托没代码如下:

delegate Object TellMeYourName(SoldierClass Soldier);//定义一个委托
TellMeYourName tell;//委托实例 
string TellMeYourNameMethod(BaseUnitClass base);//构造一个该委托类型的实例来引用具有这个原型的方法
tell=TellMeYourNameMethod;

在这个例子中,TellMeYourNameMethod方法的参数类型是BaseUnitClass,它是TellMeYourName委托的参数类型SoldierClass的基类,这种参数的逆变性是允许的。而TellMeYourNameMethod方法的返回值类型为string,是派生自TellMeYourName委托的返回值类型Object的,因此这种返回值类型的协变性也是允许的。但是有一点需要指出的是,协变性和逆变性仅仅支持引用类型,所以如果是值类型或void则不支持。

委托的简化语法


匿名方法
通常在使用委托时,往往要声明相应的方法,例如参数和返回值类型必须符合委托类型确定的方法原型。而且,在实际的游戏开发过程中,往往也需要委托这种机制来处理十分简单的逻辑,但对应的必须要创建一个新的方法和委托类型匹配,这样做会使代码看起来十分臃肿。因此,在C#2的版本中,引入了匿名方法这种机制。例如:

Action<string> tellMeYourName = delegate (string name)
{
       string intro = "My name is";
       Debug.Log(intro+name);
};

这段代码就使用了“匿名方法”这一机制。所谓的匿名就是指该方法并没有自己的名字,而是在一开始就把{}内的方法赋给了委托实例tellMeYourName。之后,我们可以直接调用tellMeYourName。例如

tellMeYourName(“ssw”);//这样便会输出 My name is ssw

常见的两个委托泛型有:Action<T>和Func<T>。其中Action<T>没有返回值,Func<T>有返回值。他们的表现形式如下:

public delegate void Action();
public delegate void Action<T1>(T1 arg1);
public delegate void Action<T1,T2>(T1 arg1,T2 arg2);//...还有很多
public delegate TResult Func<TResult>();
public delegate TResult Func<T1,TResult>(T1 arg1);
public delegate TResult Func<T1,T2,TResult>(T1 arg1,T2 arg2);//...还有很多

除此以外,还有一些在实际开发过程中可能遇到的C#预置的委托类型,例如返回值为bool的委托类型Predicate<T>。它的签名如下:

public delegate bool Predicate<T>(T obj);

Predicate<T>常常会在过滤和匹配目标时发挥作用。
返回值为int的委托类型Comparison<T>。它的签名如下

public delegate int Comparison<in T>(T x,T y)


关于泛型修饰符in(泛型修饰符) - C# 参考 | Microsoft Learn

————————————————
原文链接:https://blog.csdn.net/ssw940521/article/details/78446451

猜你喜欢

转载自blog.csdn.net/weixin_42565127/article/details/132204740