Skip to content

Action

csharp-action-deep-dive

一句话理解

Action 是 C# 内置的一种 delegate,专门用来保存“没有返回值的方法”。

你可以把它理解成:

我先把“等会儿要做的事”存起来,到了合适时机再调用它。

最基础写法

c
using System;
using UnityEngine;

public class ActionDemo : MonoBehaviour
{
    private Action onDead;
    private Action<int> onDamaged;

    private void Start()
    {
        onDead = ShowGameOver;
        onDamaged = RefreshHp;

        onDead?.Invoke();
        onDamaged?.Invoke(20);
    }

    private void ShowGameOver()
    {
        Debug.Log("显示游戏结束界面");
    }

    private void RefreshHp(int damage)
    {
        Debug.Log("扣血:" + damage);
    }
}

这里你要抓住 3 点:

Action 保存的是无参数、无返回值的方法。 Action<int> 保存的是接收一个 int 参数、无返回值的方法。 ?.Invoke() 的意思是:如果里面有方法,就调用;如果是 null,就什么也不做。

Action 的常见形态

c
Action a;                 // 无参数,无返回值
Action<int> b;            // 一个 int 参数,无返回值
Action<string, int> c;    // 两个参数,无返回值
Action<float, bool> d;    // 两个参数,无返回值

注意:Action 永远没有返回值。需要返回值时用 Func

c
Func<int, bool> checkHp; // 传入 int,返回 bool

Unity 里最常用的 Action 场景

最常见是“通知别人某件事发生了”。

c
using System;
using UnityEngine;

public class PlayerHealth : MonoBehaviour
{
    public event Action<int> OnDamaged;

    public void TakeDamage(int damage)
    {
        OnDamaged?.Invoke(damage);
    }
}

另一个脚本订阅它:

c
public class HealthUI : MonoBehaviour
{
    public PlayerHealth player;

    private void OnEnable()
    {
        player.OnDamaged += RefreshUI;
    }

    private void OnDisable()
    {
        player.OnDamaged -= RefreshUI;
    }

    private void RefreshUI(int damage)
    {
        Debug.Log("刷新血条,扣血:" + damage);
    }
}

这里的思路是:

PlayerHealth 不需要知道 UI 怎么刷新。 它只负责发出“我受伤了”的通知。 HealthUI 自己订阅这个通知,然后做自己的事。

这就是 Action 很重要的地方:让两个系统少互相依赖

Action 和 event 的区别

Action<int> OnDamaged; 是一个普通委托字段,外部脚本可能直接覆盖它或调用它。 event Action<int> OnDamaged; 更安全,外部通常只能 += 订阅、-= 取消,不能随便调用。

Unity 项目里,公开通知通常更推荐:

c
public event Action<int> OnDamaged;

三个新手坑

  1. 需要返回值时不要用 Action,用 Func
  2. 订阅了事件,记得在 OnDisable 里取消订阅。
  3. 匿名 lambda 不好取消订阅,重要监听最好保存成方法或变量。

官方参考链接:

Microsoft - System.ActionMicrosoft - System.ActionMicrosoft - DelegatesMicrosoft - EventsMicrosoft - FuncUnity - UnityActionUnity - UnityEvent

文章评价

读完这篇,留下你的看法

暂无审核通过的评价。

登录账号后才能评价。

本站访客数0总站访问量0本页访问量0