C#中首选IObservable/IObserver实现观察者模式,语义清晰、线程安全基础好、支持取消订阅与异常传递;事件适合快速原型;自定义委托适合教学或特殊调度。
在C#中实现观察者模式,核心是定义“被观察者(Subject)”和“观察者(Observer)”,让多个观察者能动态订阅、接收被观察者状态变化的通知。.NET 原生提供了 IObservable<t></t> 和 IObserver<t></t> 接口,是最轻量、标准且推荐的方式——无需手写事件委托或自定义接口,也天然支持取消订阅和异常传递。
用 IObservable/IObserver 实现标准观察者
这是最符合 .NET 理念的写法,语义清晰、线程安全基础好、可组合性强(配合 System.Reactive 可进一步增强)。
- 被观察者需实现
IObservable<t></t>,通常返回一个包装了订阅逻辑的对象(如Observable.Create<t>()</t>) - 观察者实现
IObserver<t></t>,重写OnNext(接收数据)、OnError(处理异常)、OnCompleted(通知结束) - 调用
Subscribe()建立连接;返回的IDisposable可用于主动取消订阅
示例:温度传感器模拟
// 被观察者:温度数据源
var temperatureSource = Observable.Create<double>(observer =>
{
var timer = new Timer(_ =>
{
var temp = 20 + new Random().NextDouble() * 10;
observer.OnNext(temp);
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(2));
<pre class="brush:php;toolbar:false;">return () => timer.Dispose(); // 取消时释放资源
});
// 观察者:控制台显示
var subscription = temperatureSource.Subscribe(
temp => Console.WriteLine($”当前温度:{temp:F2}°C”),
ex => Console.WriteLine($”错误:{ex.Message}”),
() => Console.WriteLine(“传感器已关闭”)
);
// 5秒后取消订阅
await Task.Delay(5000);
subscription.Dispose(); // 主动断开,timer 也会被释放
用事件(event)+ 自定义委托实现简易版
适合入门理解或轻量场景,代码直观,但需手动管理订阅列表、线程安全、异常隔离等细节。