需求
通过直接调用其他类的实例的方法我们就可以实现在不同的类之间实现数据交互和功能互动。但是有时候我们想让类的功能更加专注(单一职责原则),或者负责写触发事件模块的人并不知道需要触发哪些事件而写事件具体内容的人并不知道何时触发这些事件,这个时候我们就需要委托和事件了。
是什么
委托
委托是对方法的引用。
通俗的讲就是将方法签名交给委托,然后通过调用该委托来调用它上面的所有方法。
注意
- 声明委托要使用delegate关键字。
- 委托定义了它所引用的方法的“形式”。要指定返回类型、委托名称以及任何参数。
- 添加到委托的方法的形式要和该委托完全一致。
- 可以从别的类调用该委托实例来触发委托上的方法
事件
事件相当于委托的实例,用法和委托基本完全一致,唯一的不同是事件只能在它所处的类中触发委托给它的事件,无法通过从类外部调用该实例来触发事件,委托无此限制。
怎么用
声明委托
public delegate void Handle(string str);
定义需要注册的方法
void functionA(string str){
Debug.Log ("functionA:"+str);
}
void functionB(string str){
Debug.Log ("functionB:"+str);
}
使用委托来调用方法
定义委托类
public class MyHandle{
public Handle thisHandle;
//给委托注册方法,一次可传入任意数量符合要求的方法
public void addHandle(params Handle[] handles){
if(handles!=null)
foreach(Handle handle in handles)
thisHandle+=handle;
}
//删掉委托上的方法
public void deleteHandle(Handle handle){
if(handle!=null)
thisHandle -= handle;
}
//调用委托的方法
public void callHandle(string str){
if(thisHandle!=null)
thisHandle ("CallHandle+"+str);
}
}
实例化委托
myHandle = new MyHandle ();
注册&删除方法
//注册方法
myHandle.thisHandle += functionA;
myHandle.addHandle (functionB);
//删除方法
myHandle.thisHandle -= functionA;
myHandle.deleteHandle (functionB);
//一次注册多个方法
myHandle.addHandle (functionA,functionB);
调用委托激活方法
//通过委托内部方法调用
myHandle.callHandle ("Handle");
//直接调用委托
myHandle.thisHandle ("Handle");
使用事件来调用方法
定义事件类
public class MyEvent{
public event Handle thisEvent;
//给事件注册方法,一次可传入任意数量符合要求的方法
public void addEvent(params Handle[] handles){
if(handles!=null)
foreach(Handle handle in handles)
thisEvent+=handle;
}
//删掉事件上的方法
public void deleteEvent(Handle handle){
if(handle!=null)
thisEvent -= handle;
}
//调用事件的方法
public void callEvent(string str){
if(thisEvent!=null)
thisEvent ("CallEvent+"+str);
}
}
实例化事件
myEvent = new MyEvent ();
注册&删除方法
//注册方法
myEvent.thisEvent += functionA;
myEvent.addEvent (functionB);
//删除方法
myEvent.thisEvent -= functionA;
myEvent.deleteEvent (functionB);
//一次注册多个方法
myEvent.addEvent (functionA,functionB);
调用事件激活方法
//通过事件内部方法调用
myEvent.callEvent ("Event");
//直接调用事件
myEvent.thisEvent ("Event");
编译不通过,无法在事件所在的类外直接调用事件来激活方法,直接报错如下:
转载请注明出处:http://blog.csdn.net/ylbs110/article/details/50695420
完整脚本
using UnityEngine;
using System.Collections;
public delegate void Handle(string str);
public class MyDelegate : MonoBehaviour {
MyHandle myHandle;
MyEvent myEvent;
void Start () {
myHandle = new MyHandle ();
myEvent = new MyEvent ();
//注册方法
myHandle.thisHandle += functionA;
myHandle.addHandle (functionB);
//删除方法
myHandle.thisHandle -= functionA;
myHandle.deleteHandle (functionB);
//一次注册多个方法
myHandle.addHandle (functionA,functionB);
//通过委托内部方法调用
myHandle.callHandle ("Handle");
//直接调用委托
myHandle.thisHandle ("Handle");
//注册方法
myEvent.thisEvent += functionA;
myEvent.addEvent (functionB);
//删除方法
myEvent.thisEvent -= functionA;
myEvent.deleteEvent (functionB);
//一次注册多个方法
myEvent.addEvent (functionA,functionB);
//通过事件内部方法调用
myEvent.callEvent ("Event");
//直接调用事件
// myEvent.thisEvent ("Event");
}
void functionA(string str){
Debug.Log ("functionA:"+str);
}
void functionB(string str){
Debug.Log ("functionB:"+str);
}
}
public class MyHandle{
public Handle thisHandle;
//给委托注册方法,一次可传入任意数量符合要求的方法
public void addHandle(params Handle[] handles){
if(handles!=null)
foreach(Handle handle in handles)
thisHandle+=handle;
}
//删掉委托上的方法
public void deleteHandle(Handle handle){
if(handle!=null)
thisHandle -= handle;
}
//调用委托的方法
public void callHandle(string str){
if(thisHandle!=null)
thisHandle ("CallHandle+"+str);
}
}
public class MyEvent{
public event Handle thisEvent;
//给事件注册方法,一次可传入任意数量符合要求的方法
public void addEvent(params Handle[] handles){
if(handles!=null)
foreach(Handle handle in handles)
thisEvent+=handle;
}
//删掉事件上的方法
public void deleteEvent(Handle handle){
if(handle!=null)
thisEvent -= handle;
}
//调用事件的方法
public void callEvent(string str){
if(thisEvent!=null)
thisEvent ("CallEvent+"+str);
}
}