委托delegate
委托可以理解为像类一样,声明的一种方法类型。
委托对象可以被赋值,注册和注销方法。委托对象必须被赋值才可使用。委托的使用类内和类外无差别。
public delegate void MyDelegate(int i);
public MyDelegate myDelegate ;
public void Start()
{
//委托delegate
myDelegate = new MyDelegate(DoThing);
myDelegate = DoThing;//等号赋值,更改委托内容
myDelegate += DoThing;
myDelegate -= DoThing;
myDelegate.Invoke(1);
}
public void DoThing(int i)
{
Debug.Log(i);
}
通过Invoke()调用delegate;
事件event
事件是对委托的一个限定,事件对象不需要被赋值,也不能被赋值,可以注册和注销方法。也可以注册和注销委托。
不论声明为public还是private,事件对象在类外只能在+=号和-=号的左边,意味着在声明此事件的类外,无法使用,只能注册和注销方法。
public delegate void MyDelegate(int i);
public MyDelegate myDelegate ;
public event Mydelegate myEvent;
public void Start()
{
//委托使用
myDelegate = new MyDelegate(DoThing);
myDelegate= DoThing;//等号赋值,更改委托内容
myDelegate += DoThing;
myDelegate -= DoThing;
//事件使用
myEvent = DoThing; //在声明event的类中,可以为event赋值。
myEvent = myDelegate;
myEvent += DoThing;
myEvent -=DoThing;
myEvent += myDelegate;
myEvent -=MyDelegate;
myEvent.Invoke(1);
}
public void DoThing(int i)
{
Debug.Log(i);
}
通过Invoke()调用event;
Action
Action和Func可以理解为系统定义好的带泛型的delegate。Action是无返回值的。
Action<T>的泛型T,代表参数。
从使用上就可以看出来;
public Action<int> action;
public void Start()
{
action = DoThing;
action += DoThing;
action -= DoThing;
action.Invoke(1);
}
public void DoThing(int i)
{
Debug.Log(i);
}
Func
Action和Func可以理解为系统定义好的带泛型的delegate。Func是有返回值的。
Func<T,K>的前n-1个泛型代表参数, 最后一个泛型代表返回值类型。
public Func<int,int> action;
public void Start()
{
action = DoThing;
action += DoThing;
action -= DoThing;
int num = action.Invoke(1);
}
public int DoThing(int i)
{
Debug.Log(i);
return i+1;
}
如果向Func添加了多个不同方法,则返回值为最后添加的方法的返回值。
UnityAction
UnityAction是Unity对C#中Action的再次封装。是更适合在Unity中使用的一种泛型委托。
UnityAction对象可以用于Unity内的.AddListener()。
用法和Action一样。
public UnityAction<int> action;
public void Start()
{
action = DoThing;
action += DoThing;
action -= DoThing;
action.Invoke(1);
}
public void DoThing(int i)
{
Debug.Log(i);
}
UnityEvent
UnityEvent可以在面板中添加监听事件,也可以在代码中添加监听事件或UnityAction。而且这两个模式不会互通。
public UnityEvent<int> event0;
public UnityEvent<int, string> event1;
他可以在Inspector面板显示,并且添加方法,就和Button按钮一样。
看起来是不是很眼熟?我们常用的UGUI中的Button点击事件,就继承自UnityEvent。
在Inspector中添加的事件,不受定义UnityEvent的参数限制,并且在代码中无法注销。(RemoveAllListeners无法注销在面板中设置的监听。)
Invoke的参数也只对代码中add的事件有效,在Inspector面板中添加的事件如果有参数,调用时使用面板设置的参数。
下面是UInityEvent在代码中的使用:
public UnityEvent<int> event0;
public UnityEvent<int, string> event1;
void Start()
{
event0.AddListener(DoThing_Int);
event1.AddListener(DoThing_Int_Str);
· //只会注销在代码中add的Listener,面板定义的监听还保存在event0中
event0.RemoveAllListeners();
event0.Invoke(0);
event1.Invoke(0, "zzz");
}
public void DoThing()
{
Debug.Log("DoThing");
}
public void DoThing_Int(int i)
{
Debug.Log("DoThing_Int"+ i);
}
public void DoThing_Int_Str(int i, string str)
{
Debug.Log("DoThing_Int_Str" + i+ str);
}