6

I am working on a Silverlight application where I made excessive use of the observer pattern. In my implementation I have created two interfaces IObservable<T> and IObserver<T>. The former contains methods to attach and detach observers to the observable. The latter has a method Notify(IObservable<T> observable, ...) that is called by the observable passing itself as parameter via observer.Notify(this, ...) when the observable has changed its state.

Now I have stumbled upon "events" and for me it seems pretty much as if this were an implementation of the observer pattern, just with delegates instead of the aforementioned Notify-method. Is that right?

I do not know much about delegates and do not want to spend hours on rewriting my code just to end up with code that does the same thing as it already does. On the other hand events might be superior to the interface-based observer pattern. Am I missing something?

1 Answer 1

12

Events are an implementation of the observer pattern.

An event is implemented as a list of methods to be called when the vent is raised.

Delegates are method references: in contrast to Java, C# offers a way to refer to a method.

It's not a priori better to use events than implement the observer pattern oneself. But events offer a quite generic way to do it, and are in many cases highly optimized for the task, thus give a more efficient and convenient way organize this.

A delegate is defined by the signature of the expected method. For instance with:

public delegate void FooMethod (Bar x, Baz y); 

You define a delegate for void methods given a Bar and a Baz. So if you have an instance of the following class:

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

Then you can refer to the method:

Qux q = new Qux(); FooMethod fm = q.Method; 

An event is thus a list of delegates with the same signature:

You define an event as:

private event FooMethod SomeEvent; 

You can add delegates (listeners) by using the += operator:

SomeEvent += q.Method; 

remove the delegate by the -= operator and call the event with:

SomeEvent(new Bar(), new Baz()); 

As if you call a single method that does the dispatching.

By calling the event, all the registered delegates will be called, in the order of registration.

Note: By calling SomeEvent(new Bar(), new Baz()); this does not mean every delegate receives new instances: the instances are constructed first and shared over all delegate calls.

Conclusion: I think the C# designers did a good job introducing observer patterns since the programmer is no longer responsible to program it correctly his/herself. Furthermore the events are easy to understand and use convenient syntax. In special situations however programmers can be required to implement an observer him/herself. But these are very rare occasions.

Sign up to request clarification or add additional context in comments.

7 Comments

Right now my observables have a method NotifyAll() that loops through the attached observers and calls its Notify-method. This is equivalent to SomeEvent(new Bar(), New Baz()). Later I will need to notify only certain observers and this decision I'll have to fell on runtime. Is there a way to achieve it with events?
@JCvanDamme: indeed. The advantage is thus that the programmer doesn't need to make sure such methods are implemented correctly which is of course always nice. As they say: Software design is the study on how to make systems fail proof. The universe is an experiment to produce bigger fools. And currently the universe is winning :P.
(EDIT: With 'it' I mean something like 'if (observer B is attached) then do not notify observer A who is also attached')
to notify only certain observers - this is one of the reasons why standard event have sender as a parameter of event handler. In C# filtering (not processing event for certain subscribers) is a job of subscriber himself. All event handlers are called when event is raised (called), but each can make own decision whenever to run or not to run.
I offer to read comparison of different implementations of Observer Pattern on this link: github.com/millermedeiros/js-signals/wiki/…
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.