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

在 C# 中实现观察者模式,核心是定义一个被观察对象(主题)和多个观察者,当主题状态发生变化时,自动通知所有注册的观察者。这种设计模式非常适合处理事件驱动的场景,比如 UI 更新、消息广播等。
观察者模式的基本结构
观察者模式包含两个主要角色:
- Subject(主题):维护观察者列表,提供注册、注销和通知方法。
- Observer(观察者):实现一个更新接口,用于接收主题的通知。
在 C# 中,可以通过接口和委托两种方式来实现。下面分别介绍具体做法。
使用接口手动实现观察者模式
定义观察者和主题接口,让具体类实现它们。
示例代码:
// 观察者接口
public interface IObserver
{
void Update(string message);
}
<p>// 主题接口
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify(string message);
}</p><p>// 具体主题
public class NewsAgency : ISubject
{
private List<IObserver> _observers = new List<IObserver>();</p><pre class='brush:php;toolbar:false;'>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("凤凰");
<p>agency.Attach(channelA);
agency.Attach(channelB);</p><p>agency.PublishNews("今日天气晴朗");</p><p>// 输出:
// 新闻机构发布:今日天气晴朗
// 央视 收到新闻:今日天气晴朗
// 凤凰 收到新闻:今日天气晴朗</p>
利用 C# 委托和事件简化实现
C# 的事件机制天生适合观察者模式。通过 event 和 delegate,可以更简洁地实现松耦合通信。
示例代码:
public class Stock
{
// 定义委托
public delegate void PriceChangedHandler(string symbol, double price);
<pre class='brush:php;toolbar:false;'>// 定义事件
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);
}
}
观察者订阅事件:
Musho
AI网页设计Figma插件
76
查看详情
var stock = new Stock("AAPL", 150.0);
<p>// 订阅事件
stock.PriceChanged += (symbol, price) =>
{
Console.WriteLine($"股票 {symbol} 价格变更为:{price}");
};</p><p>stock.Price = 155.0; // 输出:股票 AAPL 价格变更为:155</p>
这种方式更符合 C# 的编程习惯,代码更简洁,且线程安全由语言机制部分保障。
使用 IObservable 和 IObserver 接口(响应式扩展)
C# 还提供了内置的 IObservable
public class Sensor : IObservable<double>
{
private List<IObserver<double>> _observers = new List<IObserver<double>>();
<pre class='brush:php;toolbar:false;'>public IDisposable Subscribe(IObserver<double> 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<IObserver<double>> _observers;
private IObserver<double> _observer;
public Unsubscriber(List<IObserver<double>> observers, IObserver<double> observer)
{
_observers = observers;
_observer = observer;
}
public void Dispose()
{
_observers.Remove(_observer);
}
}
}
使用方式:
var sensor = new Sensor(); <p>var observer = new MyObserver(); var subscription = sensor.Subscribe(observer);</p><p>sensor.Measure(23.5); // 触发通知</p><p>subscription.Dispose(); // 取消订阅</p>
其中 MyObserver 需要实现 IObserver
基本上就这些。C# 提供了多种实现观察者模式的方式:手动接口实现适合学习原理,事件机制最常用也最自然,而 IObservable 则适用于高级异步场景。选择哪种方式取决于项目复杂度和需求。
以上就是C# 怎么实现一个观察者模式_C# 观察者模式实现方法详解的详细内容,更多请关注其它相关文章!
# 多个
# 湖北营销推广哪家好
# 渤海新区seo推广
# 建设网站最终的目标
# 抖音seo系统方案
# 校园网站推广活动有哪些
# 网站优化建设怎么做的
# 页面seo推广工具
# 网站程序建设
# 从化市网站建设价格表
# 乐云seo新闻发稿平台
# 相关文章
# 两种
# react
# 央视
# 新特性
# 游戏开发
# 你在
# 有哪些
# 今日
# 适用于
# gate
# .net
# c#
# ai
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
自定义Bag-of-Words实现:处理带负号的词汇权重
c++如何使用chrono库处理时间_c++标准库时间与日期操作
拼多多购物车商品数量无法修改如何处理 拼多多购物车操作优化方法
uc浏览器网页版入口 uc浏览器网页版最新网址
双系统安装时,如何设置默认启动系统? msconfig命令了解一下!
J*aScript中高效清空DOM列表元素:解决for循环中断与任务管理问题
J*aScript教程:根据元素文本内容动态设置背景色
qq邮箱日历功能怎么用_创建日程与会议邀请的技巧
yandex入口引擎手机版 yandex安卓版下载入口
Django模型中自动计算可用余额的实现方法
python3时间如何用calendar输出?
探索高级语言到C/C++的转译路径:以Go为例及内存管理策略
JUnit5/Mockito:优雅测试内部依赖与异常处理的实践
神经网络二分类模型训练异常:高损失与完美验证准确率的排查与修正
不同用户不同价格! 索尼开启账户个性化定价测试
汽水音乐在线解析 汽水音乐在线解析入口
处理动态列数据:J*a ArrayList的正确初始化与字符累加教程
海棠电脑版入口_通过电脑访问海棠官网阅读
lar*el怎么安全地存储和获取配置文件中的敏感信息_lar*el敏感信息安全存储方法
俄罗斯Yandex免登录入口_Yandex搜索引擎官网一键直达
Excel中VLOOKUP的第四个参数是干什么用的_Excel VLOOKUP第四参数作用解析
c++ 获取系统当前时间 c++时间戳获取方法
优化MinIO list_objects_v2 操作的性能瓶颈与最佳实践
CSS布局中意外空白:解决padding-top导致的顶部间距问题
Lar*el Form Request中唯一性验证在更新操作中的正确实现
格力空气能E5故障代码是什么情况_格力空气能E5代码解析与应对措施
Go调试环境为何无法启动_Go调试器启动失败原因与解决策略
Django通过AJAX异步上传图片并保存至模型的完整指南
Linux如何构建多环境配置管理_Linux多环境配置方案
铁路12306官网网页端快速入口 铁路12306官方首页登录教程
UC浏览器官网入口2025最新 UC浏览器网页版正式地址
2026年CSGO开箱网站推荐 CSGO开箱平台精选
印象笔记如何设离线包出差查阅_印象笔记设离线包出差查阅【离线阅读】
Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题
Surface怎么安装系统 微软Surface Pro U盘重装win11教程
蛙漫官方正版入口 蛙漫网页在线全集免费观看
composer的"require-dev"部分是用来做什么的?
汽水音乐车机版横屏版7.1 汽水音乐车机版横屏版下载入口
Python中如何避免重复条件判断:利用数据结构实现动态逻辑
C++如何操作注册表_Windows平台下C++读写注册表的API函数详解
魅族17怎样用浏览器译外语网页_iPhone魅族17浏览器译外语网页【即时翻译】
Word2013如何插入视频和音频媒体_Word2013媒体插入的多媒体支持
FullCalendar 自定义按钮样式定制指南
Windows7怎么硬盘安装 Windows7提取ISO镜像到非系统盘并运行setup.exe实现硬盘直装【教程】
J*a 递归快速排序中静态变量的状态管理与陷阱
蛙漫画网页版全站入口 蛙漫热门作品免费浏览
整合Supabase认证与Django模型:跨模式迁移的解决方案
HTML元素状态管理:根据DIV内容动态启用/禁用按钮
如何使用J*aScript精确选择并批量修改特定父元素下子链接的样式
2306选座时如何选靠窗位置_12306选座靠窗座位查看方法解析


2025-11-03
浏览次数:次
返回列表