0

0

C# 怎么实现一个观察者模式_C# 观察者模式实现方法详解

煙雲

煙雲

发布时间:2025-11-03 13:25:02

|

673人浏览过

|

来源于php中文网

原创

C#中实现观察者模式的核心是定义主题与观察者,通过接口、事件或IObservable方式实现状态变更时的自动通知,适用于事件驱动场景。

c# 怎么实现一个观察者模式_c# 观察者模式实现方法详解

在 C# 中实现观察者模式,核心是定义一个被观察对象(主题)和多个观察者,当主题状态发生变化时,自动通知所有注册的观察者。这种设计模式非常适合处理事件驱动的场景,比如 UI 更新、消息广播等。

观察者模式的基本结构

观察者模式包含两个主要角色:

  • Subject(主题):维护观察者列表,提供注册、注销和通知方法。
  • Observer(观察者):实现一个更新接口,用于接收主题的通知。

在 C# 中,可以通过接口和委托两种方式来实现。下面分别介绍具体做法。

使用接口手动实现观察者模式

定义观察者和主题接口,让具体类实现它们。

示例代码:

// 观察者接口
public interface IObserver
{
    void Update(string message);
}

// 主题接口 public interface ISubject { void Attach(IObserver observer); void Detach(IObserver observer); void Notify(string message); }

// 具体主题 public class NewsAgency : ISubject { private List _observers = new List();

public void Attach(IObserver observer) => _observers.Add(observer);
public void Detach(IObserver observer) => _observers.Remove(observer);

public void Notify(string news)
{
    foreach (var observer in _observers)
    {
        observer.Update(news);
    }
}

// 模拟新闻发布
public void PublishNews(string news)
{
    Console.WriteLine($"新闻机构发布:{news}");
    Notify(news);
}

}

// 具体观察者 public class NewsChannel : IObserver { private string _name;

public NewsChannel(string name) => _name = name;

public void Update(string message)
{
    Console.WriteLine($"{_name} 收到新闻:{message}");
}

}

使用示例:

var agency = new NewsAgency();
var channelA = new NewsChannel("央视");
var channelB = new NewsChannel("凤凰");

agency.Attach(channelA); agency.Attach(channelB);

agency.PublishNews("今日天气晴朗");

// 输出: // 新闻机构发布:今日天气晴朗 // 央视 收到新闻:今日天气晴朗 // 凤凰 收到新闻:今日天气晴朗

利用 C# 委托和事件简化实现

C# 的事件机制天生适合观察者模式。通过 eventdelegate,可以更简洁地实现松耦合通信。

示例代码:

public class Stock
{
    // 定义委托
    public delegate void PriceChangedHandler(string symbol, double price);
// 定义事件
public event PriceChangedHandler PriceChanged;

private string _symbol;
private double _price;

public Stock(string symbol, double price)
{
    _symbol = symbol;
    _price = price;
}

public double Price
{
    get => _price;
    set
    {
        _price = value;
        OnPriceChanged(); // 触发事件
    }
}

protected virtual void OnPriceChanged()
{
    PriceChanged?.Invoke(_symbol, _price);
}

}

观察者订阅事件:

无涯·问知
无涯·问知

无涯·问知,是一款基于星环大模型底座,结合个人知识库、企业知识库、法律法规、财经等多种知识源的企业级垂直领域问答产品

下载

var stock = new Stock("AAPL", 150.0);

// 订阅事件 stock.PriceChanged += (symbol, price) => { Console.WriteLine($"股票 {symbol} 价格变更为:{price}"); };

stock.Price = 155.0; // 输出:股票 AAPL 价格变更为:155

这种方式更符合 C# 的编程习惯,代码更简洁,且线程安全由语言机制部分保障。

使用 IObservable 和 IObserver 接口(响应式扩展)

C# 还提供了内置的 IObservableIObserver 接口,属于 .NET 的响应式扩展(Reactive Extensions, Rx),适用于更复杂的异步数据流场景。

public class Sensor : IObservable
{
    private List> _observers = new List>();
public IDisposable Subscribe(IObserver observer)
{
    if (!_observers.Contains(observer))
        _observers.Add(observer);

    return new Unsubscriber(_observers, observer);
}

public void Measure(double value)
{
    foreach (var observer in _observers)
        observer.OnNext(value);
}

private class Unsubscriber : IDisposable
{
    private List> _observers;
    private IObserver _observer;

    public Unsubscriber(List> observers, IObserver observer)
    {
        _observers = observers;
        _observer = observer;
    }

    public void Dispose()
    {
        _observers.Remove(_observer);
    }
}

}

使用方式:

var sensor = new Sensor();

var observer = new MyObserver(); var subscription = sensor.Subscribe(observer);

sensor.Measure(23.5); // 触发通知

subscription.Dispose(); // 取消订阅

其中 MyObserver 需要实现 IObserver 接口。

基本上就这些。C# 提供了多种实现观察者模式的方式:手动接口实现适合学习原理,事件机制最常用也最自然,而 IObservable 则适用于高级异步场景。选择哪种方式取决于项目复杂度和需求。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

318

2023.08.02

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

53

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

99

2025.10.23

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1024

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

66

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

450

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

5

2026.01.19

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

465

2024.01.03

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.8万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

React核心原理新老生命周期精讲
React核心原理新老生命周期精讲

共12课时 | 1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号