我在阅读MSDN文档后尝试学习观察者模式:https://learn.microsoft.com/en-us/dotnet/standard/events/observer-design-pattern。与继承一起使用时,它会出错并且不允许我创建公共观察器。下面是我的代码:
interface Book { }
class ComicBook : Book { }
class ComicBookObserver : IObserver<ComicBook>
{
public void OnCompleted() { throw new NotImplementedException(); }
public void OnError(Exception error) { throw new NotImplementedException(); }
public void OnNext(ComicBook value) { throw new NotImplementedException(); }
}
class Publisher : IObservable<Book>
{
private List<IObserver<ComicBook>> ComicBookObservers = new List<IObserver<ComicBook>>();
public IDisposable Subscribe(IObserver<Book> observer)
{
if (observer is IObserver<ComicBook>)
ComicBookObservers.Add(observer);
return null;
}
}
class Main
{
public static void main(string[] args)
{
Publisher p = new Publisher();
p.Subscribe(new ComicBookObserver());
}
}
我在p.Subscribe(new ComicBookObserver());
收到错误:
Cannot convert from 'ComicBookObserver' to 'System.IObserver<Book>'
为什么会这样,因为漫画书也是一本书。这是不允许的吗?我是否必须为所有不同类型的书籍创建Subcribe
方法?
在您的示例中,ComicBookObserver
实现了IObserver<ComicBook>
,因此它希望看到ComicBook
。
Publisher
实现IObservable<Book>
,因此输出Book
。
Book
接口不满足ComicBookObserver
所需的派生ComicBook
类型。
如果您需要观察特定类型,那么是的,您需要多次订阅特定于这些类型的订阅者。
您可以使用 RxOfType<ComicBook>()
方法从您的IObservable<Book>
创建新的可观察量。
例如:
发布者 p = 新发布者((; p.OfType((.订阅(新漫画观察家(((;
这样做的好处是,只会观察类型ComicBook
的项目,并且不需要执行任何其他类型检查。
我认为你可以继续你的模式,但添加一个皱纹。 我会让 ComicBook 观察者实现IObserver<Book>
然后在您的实现中您需要处理ComicBook
项目并丢弃其余项目。 可以说,您将为其他观察者订阅其他类型的书籍。 他们也会遵循这种模式。
interface Book { }
class ComicBook : Book { }
class OtherBook : Book { }
class ComicBookObserver : IObserver<Book>
{
public void OnCompleted() { throw new NotImplementedException(); }
public void OnError(Exception error) { throw new NotImplementedException(); }
public void OnNext(Book value)
{
if (value is ComicBook)
{
// logic for Comic Book values
}
}
}
class OthereBookObserver : IObserver<Book>
{
public void OnCompleted() { throw new NotImplementedException(); }
public void OnError(Exception error) { throw new NotImplementedException(); }
public void OnNext(Book value)
{
if (value is OtherBook)
{
// logic for other book values
}
}
}
class Publisher : IObservable<Book>
{
public IDisposable Subscribe(IObserver<Book> observer) { throw new NotImplementedException(); }
}
class Main
{
public static void main(string[] args)
{
Publisher p = new Publisher();
p.Subscribe(new ComicBookObserver());
p.Subscribe(new OtherBookObserver());
}
}