Observer 使用 IObservable 和 IObserver(C)
IObserver<T>
和 IObservable<T>
接口可用于在 .NET 中实现观察者模式
IObservable<T>
接口表示发送通知的类IObserver<T>
接口表示接收它们的类
public class Stock {
private string Symbol { get; set; }
private decimal Price { get; set; }
}
public class Investor : IObserver<Stock> {
public IDisposable unsubscriber;
public virtual void Subscribe(IObservable<Stock> provider) {
if(provider != null) {
unsubscriber = provider.Subscribe(this);
}
}
public virtual void OnCompleted() {
unsubscriber.Dispose();
}
public virtual void OnError(Exception e) {
}
public virtual void OnNext(Stock stock) {
}
}
public class StockTrader : IObservable<Stock> {
public StockTrader() {
observers = new List<IObserver<Stock>>();
}
private IList<IObserver<Stock>> observers;
public IDisposable Subscribe(IObserver<Stock> observer) {
if(!observers.Contains(observer)) {
observers.Add(observer);
}
return new Unsubscriber(observers, observer);
}
public class Unsubscriber : IDisposable {
private IList<IObserver<Stock>> _observers;
private IObserver<Stock> _observer;
public Unsubscriber(IList<IObserver<Stock>> observers, IObserver<Stock> observer) {
_observers = observers;
_observer = observer;
}
public void Dispose() {
Dispose(true);
}
private bool _disposed = false;
protected virtual void Dispose(bool disposing) {
if(_disposed) {
return;
}
if(disposing) {
if(_observer != null && _observers.Contains(_observer)) {
_observers.Remove(_observer);
}
}
_disposed = true;
}
}
public void Trade(Stock stock) {
foreach(var observer in observers) {
if(stock== null) {
observer.OnError(new ArgumentNullException());
}
observer.OnNext(stock);
}
}
public void End() {
foreach(var observer in observers.ToArray()) {
observer.OnCompleted();
}
observers.Clear();
}
}
用法
...
var provider = new StockTrader();
var i1 = new Investor();
i1.Subscribe(provider);
var i2 = new Investor();
i2.Subscribe(provider);
provider.Trade(new Stock());
provider.Trade(new Stock());
provider.Trade(null);
provider.End();
...