8

Are there any guidelines on when you should use a delegate for indirect association, and an observer?

In C#, you get to use delegates for simple call-backs. I guess pointers to function and pointers to member functions can be considered as delegates too (am I right?).

I realize that do use an observer, you need to create an interface, and implement it, so it is more strongly-typed and the relationship is more formal. For a delegate, as long as the function signature and accessibility matches, you can "hook them up".

Does delegates make the observer pattern moot? How do you decide on a delegate vs. an observer pattern?

Extrakun
  • 19,057
  • 21
  • 82
  • 129
  • 2
    Btw: in .NET 4, such interfaces are already there: `IObservable` and `IObserver`. And you can use the Reactive Extensions to easily compose observables and observers. – R. Martinho Fernandes Apr 07 '11 at 15:48
  • See http://stackoverflow.com/questions/550785/c-events-or-an-observer-interface-pros-cons – jpierson May 19 '11 at 03:52

3 Answers3

9

The observer pattern is already implemented for you in the form of events.

The advantage of events is that they can have multiple subscribers, while with a delegate, you can only have one. Events are better for public interfaces, and scenarios where you don't have complete control over who wants to get notified that something happens. In reality, events are just automatically managed lists of delegates. You'll have to see what makes more sense in your scenario.

Edit: As commenter Rabbi mentions, the above isn't entirely true, as any delegate can become a multicast delegate. The purpose of the event modifier is to make a delegate that can only be invoked inside the class that defines it. This is most useful for ensuring encapsulation in public interfaces.

Alex J
  • 9,905
  • 6
  • 36
  • 46
  • An event is just a special type of delegate. Isn't it so that a delegate can have multiple subscribers? I think an event is a delegate that only has operators '+=' and '-=', and a delegate can also be assigned ('=') and so you can overwrite all subscribers when using a delegate in stead of an event. Am I correct? – Rodi May 10 '11 at 14:04
  • The C# concept of event is to a delegate more or less what a property is to a field. You can change what the add/remove operations do, see example 2 [here](http://msdn.microsoft.com/en-us/library/8627sbea(v=vs.71).aspx). When you don't, it generates a [MulticastDelegate](http://msdn.microsoft.com/en-us/library/system.multicastdelegate.aspx) for you under the hood. – Alex J May 10 '11 at 14:42
  • yes. What I was trying to say though, is that events only use operators `+=` and `-=` even though you can change the behaviour of those operators by using property-like `add` and `remove` constructs. Assignment (`=` operator) cannot be done on events. I might be wrong as I am too lazy to try it out. – Rodi May 23 '11 at 10:05
  • 6
    This answer is totally wrong. and it is propagating misinformation and confusion that abounds on the internet. It is also totally beside the point with regard to the question. Any delegate can be a multicast delegate and point to multiple subscribers. What the event modifier does is restrict calling the delegate function from any object other than the defining class. A more topical answer and one that isn't just plain wrong off the bat, is jpierson's below. – Rabbi Feb 13 '12 at 00:56
  • `restrict calling the delegate function from any object other than the defining class.` Sounds like `encapsulation`. Is that true? – Ömer Faruk Almalı May 22 '14 at 12:08
  • New [events link](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/events/) (since I can't edit the answer because queue is full). – Vanity Slug - codidact.com Aug 04 '22 at 13:08
5

One advantage of the observer pattern is that if you have a large number of events that are generally always subscribed to by an interested party, then passing a single object into a method to subscribe to the events is much easier than subscribing to each event individually. With C#'s lack of specifying interfaces and methods for anonymous classes as can be done with Java, implementing the observer pattern becomes a bit more laborious so most opt for using events anyway.

Another benefit of the traditional observer pattern is that it handles better in cases where you need to interrogate the subscriber for some reason. I've come across this need with objects that pass a web-service boundary where there are problems with delegates whereas the observer pattern is just simply a reference to another object so it works fine as long as your serialization keeps integrity of references within the object graph like the NetDataContractSerializer does. In these cases it's possible to discriminate between subscribers that should be removed before making the service boundary based on whether the referenced subscriber is also within the same object graph.

jpierson
  • 16,435
  • 14
  • 105
  • 149
2

Delegates can be used to implement the observer pattern - think of events.

To do it without events take a look here: http://www.dofactory.com/Patterns/PatternObserver.aspx

It wouldn't take much to refactor that into using delegates if you preferred.

The only advantage I can think of with implementing an interface is member name consistency across all implementations.

David Neale
  • 16,498
  • 6
  • 59
  • 85