← SEARCHABLE ARCHIVE
C# · 2026-07-29

从 C# 基础到掌握 — 第 5 集

通过委托、事件和 lambda 传递操作

INTERACTIVE READING MODE →

该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。

可以直接调用方法,但稍后执行的操作本身也可以作为值传递。 C# 中的委托、事件和 lambda 表达了此流程。

代表

int Double(int value) => value * 2;

Func<int, int> operation = Double;
int result = operation(10);

Action<string> logger = message => Console.WriteLine(message);
logger("Battle started");

Func<int, int>是接收int并返回int的action,Action是没有返回值的action。 调用代码不需要知道实际正在执行哪个方法。

事件

public sealed class Player
{
    public event Action<int>? HealthChanged;
    public int Health { get; private set; } = 100;

    public void TakeDamage(int amount)
    {
        Health = Math.Max(0, Health - amount);
        HealthChanged?.Invoke(Health);
    }
}

player.HealthChanged += health => healthBar.SetValue(health);

事件通知有状态对象发生变化并导致其他对象(例如 UI 或声音)做出响应。 从外部只能订阅和取消订阅,不能随意调用事件。

订阅生命周期管理

void OnEnable()
{
    player.HealthChanged += UpdateHealth;
}

void OnDisable()
{
    player.HealthChanged -= UpdateHealth;
}

如果短寿命对象继续订阅长寿命对象的事件,则内存和调用可能会保留。 注册地点和相应的发布地点必须一起确定。

拉姆达捕获

int bonus = 5;
Func<int, int> addBonus = damage => damage + bonus;

如果 lambda 使用外部局部变量,则可以创建一个对象来存储该值。 继续在每帧重复的代码中创建捕获 lambda 可能会导致不必要的分配。

委托是操作的类型,事件为更改通知创建边界。 为了方便起见,用事件替换所有调用会导致跟踪执行顺序变得困难,因此应该在需要松耦合的地方使用它。