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> 没有返类型。