C# 委托/事件在Unity中的使用(续)
前言:
在之前一篇文章——C# delegate/event 在Unity中的使用,已经比较详细的介绍了委托、事件等在Unity中如何排布,使用,以及使用方法,这一篇主要针对,有参数的委托、事件该如何合理使用。
说明:
依旧以前一节订阅事件为例,先给出代码,解释会之后给出
// The base class EventArgs in the System namespace
public class WorkDoneEventArgs : System.EventArgs{
private string _date;
public string Date{
get{ return _date;}
set{ _date = value;}
}
// 构造器,用于构造eventArgs
public WorkDoneEventArgs(string date){
Date = date;
}
}
public class YouToberA : MonoBehaviour {
private string _date = "today";
public delegate void WorkDoneEventHandler(Object sender,WorkDoneEventArgs e);
public event WorkDoneEventHandler WorkDone;
public float workTime = 5f;
void Start () {
StartCoroutine ("Work");
}
public IEnumerator Work(){
Debug.Log ("I am working.");
for(int cnt = 0; cnt < 5;cnt++){
yield return new WaitForSeconds (workTime);
Debug.Log ("Work done!");
WorkDoneEventArgs e = new WorkDoneEventArgs (_date);
OnWorkDone (e);
}
}
private void OnWorkDone(WorkDoneEventArgs e){
WorkDoneEventHandler handler = WorkDone;
if (handler != null)
handler (gameObject,e);
}
}
代码的改变主要有以下几点:
1、首先把所有 Observer 所关心的对象属性封装为一个 EventArgs类,这样以后不管以后有多少个关心的对象属性,都能一次性传递完毕,而且可扩展,可重用。
2、关于委托(delegate)的声明也需要改变,由无参数()—>有参数(Object sender,XXXEventArgs e),其实有参数才是标准的写法,无参数只是有参数的特殊形式(空参)。第一个参数 Object 是 发送者(被观察者),通常是自己所在的对象this。第二个参数就是 事件参数,封装在一起后就可供 Observer 进行访问。
3、 事件触发后通过OnEventName() 方法访问,将事件触发与事件回调分离,分离代码逻辑,在需要的时候可避免 继承类 被其他类 监视。
观察者:
public class ObserverA : MonoBehaviour {
// need get a reference from the inspector
public YouToberA Pews;
void Awake(){
Debug.Log ("I am interested in the video");
if(Pews != null)
Pews.WorkDone += TellMe;
}
void OnDestroy(){
Debug.Log("I lose my account");
if(Pews != null)
Pews.WorkDone -= TellMe;
}
// 修改委托回调函数 的形式,由()->(Object , EventArgs)
// 建议都写成有参数这种形式,便于修改
private void TellMe(Object sender, WorkDoneEventArgs e){
Debug.Log ("I have received the new video notify");
// 访问 感兴趣的内容 e.Date
Debug.Log ("The date is: " + e.Date);
}
}
小结
这样,一个比较完整的 事件/委托实例就完成了~ :)