27
2017
09

Code : delegate,event,lambda

Code : delegate,event,lambda

Clicker

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Clicker : MonoBehaviour {

    public static Clicker instance;

    public delegate void OnClickEvent(GameObject go);
    public event OnClickEvent OnClick;

    private void Awake()
    {
        instance = this;
    }

    void Update () {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, 100))
        {
            if (Input.GetMouseButtonUp(0))
            {
                OnClick(hit.transform.gameObject);
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test0 : MonoBehaviour {

    void Start () {
        Clicker.instance.OnClick += ClickCallThis;
    }

    void ClickCallThis(GameObject go)
    {
        Debug.Log(go.name + ": Test0");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test1 : MonoBehaviour {

    void Start () {
        Clicker.instance.OnClick += ClickCallBack;
    }

    void ClickCallBack(GameObject go)
    {
        Debug.Log(go.name + ": Test1");
    }
}

delegate

delegate:标示了函数回调的规范,能够拥有一个签名(signature),并且它只能持有与它的签名相匹配的方法的引用。它所实现的功能与C/C++中的函数指针十分相似。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DelegateEvent : MonoBehaviour {

    public delegate void PlayEndHandle();
    public event PlayEndHandle PlayEndCallBack;

    public delegate string ActionHandle(int index, string message);
    public event ActionHandle ActionCallBack;

    void Start () {

        PlayEndHandle playerEndHandle = Move;
        playerEndHandle += Run;
        playerEndHandle();

        PlayEndCallBack = Move;
        PlayEndCallBack();

        PlayEndHandle runHandle = Run;
        runHandle();

        ActionHandle action = Jump;
        action(1994, "born");

        ActionCallBack = Jump;
        Debug.Log(ActionCallBack(2017, "Now"));

    }

    private void Move()
    {
        Debug.Log("Move!");
    }

    private static void Run()
    {
        Debug.Log("Run!");
    }

    private string Jump(int index, string message)
    {
        string result = string.Format("Index:{0},Message:{1}", index, message);
        Debug.Log(result);
        return result;
    }
}

event:加入event关键字,编译器会自动针对事件生成一个私有的字段(与此事件相关的委托),以及两个访问器方法,即add访问器方法以及remove访问器方法,用于对事件的Subscribe注册及Unsubscribe注销(对事件使用+=和使用-=操作时就是调用的这两个方法)。实际上声明一个委托类型的字段也可以实现这些功能。 之所以采用event而不直接采用委托,还是为了封装。可以设想一下,如果直接采用公共的委托字段,类型外部就可以对此字段进行直接的操作了,比如将其直接赋值为null。 而使用event关键字就可以保证对事件的操作仅限于add访问器方法以及remove访问器方法(即只能使用+=及-=)


lambda

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lambda : MonoBehaviour {

    private delegate void MoveHandle();
    private event MoveHandle MoveCallBack;

    private delegate void RunHandle(string message);
    private event RunHandle RunCallBack;

    private delegate string JumpHandle(int index);
    private event JumpHandle JumpCallBack;

    void Start () {
        //委托回调
        MoveCallBack = Move;
        //匿名委托
        MoveCallBack += delegate { Debug.Log("Move:2"); };
        //匿名Lambda
        MoveCallBack += () => { Debug.Log("Move:3"); };
        MoveCallBack();

        RunCallBack = Run;
        RunCallBack += delegate (string message) { Debug.Log("Run:" + message + ":1"); };
        RunCallBack += (string message) => { Debug.Log("Run:" + message + ":2"); };
        RunCallBack("1988");

        JumpCallBack = Jump;
        JumpCallBack += delegate (int index) { return index.ToString() + ":1"; };
        JumpCallBack += (int index) => { return index.ToString() + ":2"; };
        Debug.Log(JumpCallBack(2017));
    }

    private void Move()
    {
        Debug.Log("Move:1");
    }

    private void Run(string message)
    {
        Debug.Log("Run:" + message + ":0");
    }

    private string Jump(int index)
    {
        return index.ToString() + ":0";
    }
}

这里写图片描述


Action

Action:只有输入参数,无返回值的泛型委托

using System;
using UnityEngine;

public class ActionTest : MonoBehaviour {

    //Action 没有参数
    private Action BuyBookAct0;

    //Action<T> 有1个参数 
    private Action<int> BuyBookAct1;

    //Action<T,T1> 有2个参数
    private Action<int, int> BuyBookAct2;

    void Start () {

        BuyBookAct0 = new Action(BuyBook);
        BuyBookAct0();

        BuyBookAct1 = new Action<int>(BuyBook);
        BuyBookAct1(1);

        BuyBookAct2 = new Action<int, int>(BuyBook);
        BuyBookAct2(2, 3);
    }

    public void BuyBook()
    {
        Debug.Log("BuyBook:Buy 0 book");
    }

    public void BuyBook(int count)
    {
        Debug.Log("BuyBook:Buy " + count + " book");
    }

    public void BuyBook(int aCount, int bCount)
    {
        Debug.Log("BuyBook:Buy ABook " + aCount + " , BBook " + bCount);
    }
}

Func

Func:有输入参数,还有返回值的泛型委托

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FuncTest : MonoBehaviour {

    //无参数,有返回值 Func<TResult> 
    public Func<string> SendBookFunc0;

    //有参数,有返回值 Func<T,TResult> 
    public Func<int, string> SendBookFunc1;

    //传值
    public Func<string> FuncValue;

    //传值
    public Func<int, string> FuncValue2;

    void Start () {

        SendBookFunc0 = new Func<string>(SendBook);
        Debug.Log(SendBookFunc0());

        SendBookFunc1 = new Func<int, string>(SendBook);
        Debug.Log(SendBookFunc1(2));

        FuncValue = delegate { return "This is Value 3"; };
        ReceiveValue(FuncValue);

        FuncValue2 = delegate (int count) { return "This is Value " + count.ToString(); };
        ReceiveValue(5,FuncValue2);
    }

    //无参数,有返回值
    private string SendBook()
    {
        return "Send you 0 book";
    }

    //有参数,有返回值
    private string SendBook(int count)
    {
        return "Send you " + count.ToString() + " books";
    }

    //传递值
    private void ReceiveValue(Func<string> func)
    {
        string result = func();
        Debug.Log("1传进来的值是:" + result);
    }

    //传递值
    private void ReceiveValue(int count, Func<int,string> func)
    {
        string result = func(count);
        Debug.Log("2传进来的值是:" + result);
    }
}

predicate

predicate:返回bool型的泛型委托, predicate 表示传入参数为int ,返回bool的委托, Predicate有且只有一个参数,返回值固定为bool

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PredicateTest : MonoBehaviour {

    private Predicate<int> IsMorePredicate;

    void Start () {
        IsMorePredicate = new Predicate<int>(IsMore);

        bool result = IsMorePredicate(20);
        Debug.Log("20 Is More ? "+ result);

        result = IsMorePredicate(5);
        Debug.Log("5 Is More ? " + result);
    }

    private bool IsMore(int count)
    {
        if (count > 10)
        {
            return true;
        }
        return false;
    }
}

 1. Func是一种委托,这是在3.5里面新增的,2.0里面我们使用委托是用Delegate,Func位于System.Core命名空间下。
    使用委托可以提升效率,例如在反射中使用就可以弥补反射所损失的性能。

 2. 使用 Func<T,TResult> 和 Action<T> ,Action而不使用Delegate其实都是为了简化代码,使用更少的代码达到相同的效果,不需要我们显示的声明一个委托。

 3. Action<T> 和 Func<T,TResult> 的功能是一样的,只是 Action<T> 没有返类型。
上一篇:设计模式之Builder模式 下一篇:ios10.3app内好评SKStoreReviewController以及其他方式好评