Abstract
This is a tutorial article on the Observer pattern in C#. We first present the Classic Observer pattern which is one of the GoF patterns. Observe pattern is integrated into C# via the usage of Event mechanism and that is discussed next. The intended audience is Intermediate C# programmers and above.
Introduction
This is a tutorial article on the Observer pattern in C#. The intended audience is Intermediate C# programmers and above. We first present the Classic Observer pattern which is one of GoF patterns and is often mentioned in literature.
Modern language like C# has integrated Event mechanism, via which has practically integrated Observer pattern into language mechanisms. Modern usage of Observer pattern in C# is practically related to the usage of Event mechanism and Classic Observe pattern is made obsolete in C#.
The fact that the Event mechanism, in reality, provides Synchronous calls is often overlooked and not enough emphasized. Programmers often have the illusion of parallelism, which is not reality and is an important issue in today’s multi-core-processors world.
Code presented is tutorial, demo-of-concept level and for brevity does not handle or show all variants/problematic issues.
Classic Observer Pattern
Observe pattern, sometimes called Subject-Observe pattern, defines a one-to-many dependency between objects, so that when one object (Subject) changes its state, all its dependent objects (Observes) are notified and updated. We say that Observer “subscribes” with Subject to get notified of Subject’s state change. In simple words, one component (Subject) notifies other components (Observers) that state changed.
While in C# is already integrated Event keyword, that is the implementation of the Observer pattern, one can still decide to roll out his own version/implementation. Here is what Classic Observer, as described in GoF literature looks like.
Class diagram

Implementation code sample,
public class Args {}
public abstract class ASubject {
protected List < IObserver > observersList = new List < IObserver > ();
public void AddObserver(IObserver observer) {
observersList.Add(observer);
}
public void RemoveObserver(IObserver observer) {
observersList.Remove(observer);
}
}
public interface IObserver {
void Update(object subject, Args args);
}
public class Subject: ASubject {
public string SubjectState = null;
public void NotifyObservers() {
ArgsSubject args = new ArgsSubject();
args.SubjectState = this.SubjectState;
foreach(IObserver o in observersList) {
o.Update(this, args);
}
}
}
public class Observer: IObserver {
private string name;
private string observerState;
public Observer(string name) {
this.name = name;
}
public void Update(object s, Args args) {
observerState = ((ArgsSubject) args).SubjectState;
Console.WriteLine("Observer {0}'s new state is {1}", name, observerState);
}
}
public class ArgsSubject: Args {
public string SubjectState = null;
}
class Client {
public static void Main(string[] args) {
Subject s = new Subject();
s.AddObserver(new Observer("1"));
s.AddObserver(new Observer("2"));
s.AddObserver(new Observer("3"));
// Change subject state and notify observers
s.SubjectState = "ABC123";
s.NotifyObservers();
Console.ReadLine();
}
}



Join the conversation! Your thoughts help the community grow.