用事件实现观察者模式

JCv*_*mme 4 c# events observer-pattern

我正在开发一个Silverlight应用程序,我过度使用了观察者模式.在我的实现中,我创建了两个接口IObservable<T>IObserver<T>.前者包含将观察者附加到观察者的方法.后者有一个方法Notify(IObservable<T> observable, ...),observer.Notify(this, ...)当observable改变了状态时,observable 将自身作为参数传递.

现在我偶然发现了"事件",对我来说,似乎这就是观察者模式的一个实现,只是代表而不是前面提到的Notify方法.是对的吗?

我不太了解代表,并且不想花费数小时来重写我的代码只是为了最终得到与它已经做同样事情的代码.另一方面,事件可能优于基于接口的观察者模式.我错过了什么吗?

Wil*_*sem 8

事件是观察者模式的实现.

事件被实现为引发通风口时要调用的方法列表.

代理是方法引用:与Java相比,C#提供了一种引用方法的方法.

使用事件比自己实现观察者模式更好.但事件提供了一种非常通用的方式,并且在许多情况下高度优化了任务,因此提供了一种更有效和方便的方式来组织它.

委托由预期方法的签名定义.例如:

public delegate void FooMethod (Bar x, Baz y);
Run Code Online (Sandbox Code Playgroud)

您为void给定a Bar和a的方法定义委托Baz.因此,如果您有以下类的实例:

public class Qux {

    public void Method (Bar x, Baz y) {
        //do something
        return null;
    }

}
Run Code Online (Sandbox Code Playgroud)

然后你可以参考方法:

Qux q = new Qux();
FooMethod fm = q.Method;
Run Code Online (Sandbox Code Playgroud)

一个event是这样的列表delegates的相同签名:

您将事件定义为:

private event FooMethod SomeEvent;
Run Code Online (Sandbox Code Playgroud)

您可以delegate使用+=运算符添加s(侦听器):

SomeEvent += q.Method;
Run Code Online (Sandbox Code Playgroud)

-=运营商删除委托并使用以下方式调用事件:

SomeEvent(new Bar(), new Baz());
Run Code Online (Sandbox Code Playgroud)

好像你调用一个执行调度的方法.

通过调用event,delegate将按注册顺序调用所有注册的s.

注意:通过调用SomeEvent(new Bar(), new Baz());this并不意味着每个委托都接收new实例:实例首先构造并在所有委托调用上共享.

结论:我认为C#设计师在介绍观察者模式方面做得很好,因为程序员不再负责自己正确编程.此外,事件易于理解并使用方便的语法.但在特殊情况下,程序员可能需要自己实施观察者.但这些都是非常罕见的场合.

  • "仅通知某些观察者" - 这是标准事件将"sender"作为事件处理程序参数的原因之一.在`C#`过滤(不是某些订户的处理事件)是订户自己的工作.引发事件(调用)时会调用所有事件处理程序,但每个事件处理程序都可以在运行或不运行时自行决定. (2认同)