表示 C# 中 的一个高级特性—-委托。经常用于做CallBack 使用,在此就贴上一些 代码 便于自己以后的使用,表示 有点绕的感觉啊,虽然和指针有点像,指向了一个方法提,但那时还是表示有点蒙蔽。
工作类 :
internal static class Message {
public static Dictionary<GameEvent, Delegate> mEventTable = new Dictionary<GameEvent, Delegate>();
//判断是否添加监听
public static bool onAddListener(GameEvent eventType, Delegate handler) {
if (!mEventTable.ContainsKey(eventType))
{
mEventTable.Add(eventType, null);
}
Delegate d = mEventTable[eventType];
if (d != null && d.GetType() != handler.GetType()) {
Debug.LogError(eventType + "加入监听的回调与当前监听类型不符合" + d.GetType().Name + "加入类型为" + handler.GetType().Name);
return false;
}
return true;
}
// 移除判断
public static bool onRemoveListener(GameEvent eventType, Delegate handler) {
if (mEventTable.ContainsKey(eventType))
{
Delegate d = mEventTable[eventType];
if (d == null)
{
Debug.LogError("试图移除" + eventType + "但当前监听为空");
return false;
}
if (d.GetType() != handler.GetType())
{
Debug.LogError("试图移除" + eventType + "但当前监听为" + d.GetType().Name);
return false;
}
}
else {
Debug.LogError("Message不包含要移除的对象" + eventType);
return false;
}
return true;
}
//添加监听
public static void AddListener(GameEvent eventType, CallBack handler) {
if (!onAddListener(eventType, handler)) { return; }
mEventTable[eventType] =(CallBack) mEventTable[eventType] + handler;
}
public static void AddListener<T>(GameEvent eventType, CallBack<T> handler)
{
if (!onAddListener(eventType, handler)) { return; }
mEventTable[eventType] = (CallBack<T>)mEventTable[eventType] + handler;
}
//移除监听
public static void RemoveListener(GameEvent evenType,CallBack handler) {
if (!onRemoveListener(evenType,handler)) { return; }
mEventTable[evenType] = (CallBack)mEventTable[evenType] - handler;
if (mEventTable[evenType] == null){ mEventTable.Remove(evenType); }
}
public static void RemoveListener<T>(GameEvent evenType, CallBack<T> handler)
{
if (!onRemoveListener(evenType, handler)) { return; }
mEventTable[evenType] = (CallBack<T>)mEventTable[evenType] - handler;
if (mEventTable[evenType] == null) { mEventTable.Remove(evenType); }
}
//广播监听
public static void Broadcast(GameEvent eventType) {
if (!mEventTable.ContainsKey(eventType)) {
Debug.Log("广播" + eventType + " 未被添加监听");
return; }
Delegate d;
if (mEventTable.TryGetValue(eventType, out d)) {
CallBack callback = d as CallBack;
if (callback != null)
{
callback();
}
else {
Debug.LogError("广播" + eventType + " 里方法为空");
}
}
}
public static void Broadcast<T>(GameEvent eventType,T arg1)
{
if (!mEventTable.ContainsKey(eventType)) { return; }
Delegate d;
if (mEventTable.TryGetValue(eventType, out d))
{
CallBack<T> callback = d as CallBack<T>;
if (callback != null)
{
callback(arg1);
}
else
{
Debug.LogError("广播" + eventType + "为空");
}
}
}
}
事件类:
public enum GameEvent {
Gameover,
KillEnemy,
}
委托的声明类
//无传入变量的
public delegate void CallBack();
// 一个变量的泛型模板
public delegate void CallBack<T>(T arg1);
外部使用委托:
Class A;
//声明一个委托
private CallBack<Transform> callback;
//提供一个对外设置的接口
public void SetCallBack(CallBack<Transform> _callbak) {
callback = _callbak;
}
private void onFinsh(Transform t){
//条件语句 如果真就执行相应的回掉函数
if(xxx){
//执行的是B中的funA;
callback(t);
}
}
---------
另一个类中
Class B;
//得到一个A的对象
private A a;
//设置委托
a.SetCallBack(funA);
//funA
void funA (Transform t){
XXXX;
}
PS: 委托还可以多播, 及组合,一个委托和添加多个方法。依次执行。
总结: 委托就是可以去调用另一个类中的方法,其实这完全可以通过在调用的地方实例化一个相应的类来实现,但是委托的出现,大大的减少了2个类之前的耦合性。类似于观察者模式的一个实现。