Appearance
delegate
delegate 是什么
delegate 是“方法类型”。普通变量保存数据,delegate 变量保存方法。
c
public delegate void DamageHandler(int damage);这句话的意思是:我定义了一种方法形状,它必须:
c
返回 void
参数是 int所以这种方法可以赋给它:
c
void ShowDamage(int damage)
{
Debug.Log($"受伤:{damage}");
}最小完整例子
c
public delegate void DamageHandler(int damage);
DamageHandler onDamaged;
void Start()
{
onDamaged = ShowDamage;
onDamaged += PlaySound;
onDamaged?.Invoke(10);
}
void ShowDamage(int damage)
{
Debug.Log($"飘字:-{damage}");
}
void PlaySound(int damage)
{
Debug.Log("播放受伤音效");
}+= 是添加一个方法。 -= 是移除一个方法。 ?.Invoke() 是安全调用,防止没有订阅者时报空引用。
Action 和 Func
很多时候不用自己写 delegate,直接用系统内置的:
c
Action<int> onDamaged; // 无返回值,参数 int
Func<int, bool> isDeadChecker; // 参数 int,返回 bool记法:
c
Action:只做事,不返回结果
Func:做完后返回结果,最后一个泛型类型是返回值event 是什么
event 可以理解成“受保护的 delegate”。外部只能订阅和取消订阅,不能随便触发。
c
public event Action<int> OnDamaged;
public void TakeDamage(int damage)
{
OnDamaged?.Invoke(damage);
}监听方:
c
void OnEnable()
{
player.OnDamaged += RefreshHpUI;
}
void OnDisable()
{
player.OnDamaged -= RefreshHpUI;
}Unity 里常见模式就是:OnEnable 订阅,OnDisable 取消订阅。
常见坑
签名必须匹配,参数和返回值对不上就不能赋值。 委托可能是 null,调用前用 ?.Invoke()。 匿名 lambda 不好取消订阅,需要取消时最好保存成变量。 event 更适合公开“某件事发生了”的通知,普通 delegate 更适合内部回调或策略传递。
参考链接Microsoft C# Delegatesdelegate 关键字Microsoft ActionMicrosoft FuncMicrosoft EventsUnity UnityEvent