C# 委托的一些总结

函数回调机制——委托

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则不支持。

————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————
————————————————————————————————————————————

但.Net也提供了定义好的委托,我们可以直接使

示例理解

例子1:Action

using UnityEngine;
using System.Collections;
using System;
public class ActionTest : MonoBehaviour {
    void Start () {
        Action action = XXX;
        action();
    }
    void XXX()
    {
        Debug.Log("100");
    }
}

例子2:Action

using UnityEngine;
using System.Collections;
using System;
public class ActionTest : MonoBehaviour {
    void Start () {
        Action<string> action = XXX;
        action("unity C#");
    }
    void XXX(string name)
    {
        Debug.Log(name);
    }
}

例子3:

Action<T1,T2>
using UnityEngine;
using System.Collections;
using System;
public class ActionTest : MonoBehaviour {
    void Start () {
        Action<string,int> action = XXX;
        action("unity C#",100);
    }
    void XXX(string name,int score)
    {
        Debug.Log(string.Format("{0}  {1}",name,score);
    }
}
#region Action的用法
    ///Action<T>的用法
    ///这里的T为代理函数的传入类型,无返回值
    Action<string[]> action = delegate(string[] x)
    {
        var result = from p in x
                     where p.Contains("s")
                     select p;
        foreach (string s in result.ToList())
        {
            Console.WriteLine(s);
        }
    };
    string[] str={ "charlies","nancy","alex","jimmy","selina"};
    action(str);
    Console.ReadKey();
#endregion
上面的例子是通过传入的String类型的数组,找出其中包含有字符s的项,然后输出到控制台。

例子4:Func --是有返回值的


using UnityEngine;
using System.Collections;
using System;
public class FuncTest : MonoBehaviour {
    void Start () {
        Func< int > func= XXX;
       Debug.Log( func() );
    }
    int XXX()
    {
        return 10;
    }
}

例子5: Func<T,TResult>

using UnityEngine;
using System;

public Class FuncTest:MonoBehaviour{
   void Start(){
       Func<string ,int> func= CallStringLength;
     }

    int CallStringLength(string str){
         return str.Lenth;
     }
}

例子6:

Func<string> func=delegate(){
    return "我是Func<TResult>委托返回的结果";
}

Predicate只能接受一个传入参数,返回值为bool类型

#region Predicate
  ///bool Predicate<T>的用法
    ///输入一个T类型的参数,返回值为bool类型
    Predicate<string[]> predicate = delegate(string[] x)
    {
        var result = from p in x
                     where p.Contains("s")
                     select p;
        if (result.ToList().Count > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    };
    string[] _value = { "charlies", "nancy", "alex", "jimmy", "selina" };
    if (predicate(_value))
    {
        Console.WriteLine("They contain.");
    }
    else
    {
        Console.WriteLine("They don't contain.");
    }
    Console.ReadKey();
#endregion

上面的代码其实也是判断String数组中有没有包含s的项,有的话就在控制台打印出 They contain.没有的话就打印出They don’t contain

参考资料:
https://blog.csdn.net/ssw940521/article/details/78446451
https://www.cnblogs.com/zhaoqingqing/p/3778716.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值