C#委托能否容纳对象集合?如何用委托实现观察者模式?
问题解答
问题1:C#中的委托能否包含对象集合?
C# 里的委托本身并不是对象集合,但它支持多播特性——一个委托实例可以包含多个方法引用,这些方法可以属于不同的对象。你可以把多个对象的同签名方法注册到同一个委托实例上,调用委托时会依次执行所有注册的方法。本质上是委托内部维护了一个方法调用列表,而非直接存储对象,但通过关联对象的方法,间接实现了对多个对象的回调能力。
问题2:用委托实现观察者模式,替代集合触发更新
实现思路
之前你用List<Student>存储订阅者并遍历触发Update,现在可以用多播委托替代集合,实现更简洁的逻辑:
- 定义一个和
Student.Update方法签名匹配的委托类型; - 在
Academy类中声明该委托的字段,用来存储所有订阅的更新方法; Attach方法负责将学生的Update方法注册到委托实例,Detach方法则移除对应方法;- 在
Message属性的setter中调用委托,自动触发所有已注册学生的Update方法。
完整代码实现
// 定义委托,签名与Student.Update方法一致 public delegate void UpdateMessageHandler(string message); public class Academy { private string _message; // 用委托替代List<Student>存储订阅者的更新方法 private UpdateMessageHandler _updateHandlers; public string Name { get; } public string Address { get; } public Academy(string name, string address) { Name = name; Address = address; } public string Message { get => _message; set { _message = value; // 调用委托,触发所有订阅者的更新(空判断避免空引用) _updateHandlers?.Invoke(_message); } } public void Attach(Student student) { // 将学生的Update方法添加到委托实例 _updateHandlers += student.Update; } public void Detach(Student student) { // 从委托实例中移除学生的Update方法 _updateHandlers -= student.Update; } } public class Student { public string Name { get; } public Student(Academy academy, string name) { Name = name; } // 符合委托签名的更新方法 public void Update(string message) { Console.WriteLine($"学生{Name}收到通知:{message}"); } } // 测试代码 class Program { static void Main() { var p = new Academy("College", "3rd Street"); var s1 = new Student(p, "Joe"); var s2 = new Student(p, "John"); var s3 = new Student(p, "Susan"); p.Attach(s1); p.Attach(s2); p.Attach(s3); p.Message = "Module A has been cancelled!"; p.Detach(s2); p.Message = "Module B has been cancelled!"; } }
关于“将对象添加到非集合类型中”的说明
这里不是把对象直接存入委托(非集合类型),而是把对象的方法注册到多播委托中。委托内部会维护一个方法调用列表,每个注册的方法都关联着对应的对象实例,调用委托时就会触发对应对象的Update方法,最终实现和集合存储对象然后遍历调用完全一致的效果。
内容的提问来源于stack exchange,提问作者Aleksandar
相关产品推荐
相关产品推荐

