Welcome to SpellCoder Sign in | Join | Help

Observer Pattern in C# = Events & delegates

One of the most interesting patterns in Design Patterns is the Observer pattern which is listed under Behavioral Patterns, it is really important how to make other classes which are interested in the state of another object get notified when the state changed.

To read more about Observer pattern
This is the classic Observer pattern which used to be good with C++ and Java, however in C# you can implement the same idea using Delegates and Events which is really more concise and elegant way of writing this pattern
using System;
using System.Collections.Generic;
using System.Text;

namespace Patterns
{
delegate void StateChangeHandler(State newState);

enum State
{
State1, State2, State3
}

class Product
{
private State _state;

public State MyState
{
get { return _state; }
set
{
if (_state != value)
{
_state = value;
Notify();
}
}
}

private void Notify()
{
if (_onChange != null)
_onChange(_state);
}

private event StateChangeHandler _onChange;

public event StateChangeHandler OnStateChange
{
add
{
_onChange += value;
}
remove
{
_onChange -= value;
}
}
}
}
Take a look on the previous code, the Product class has an important piece of info called _state, and is encapsulated in the property MyState, this class expects that other classes may be interested in observing the changes in the MyState, so the class adds another member which is an Event (_onChange) of type StateChangeHandler delegate, and encapsulated in the Event Property called OnStateChange, and in the setter of the property MyState a small check is made to see whether the new value is different than the older value then the event gets fired.
A typical class which makes use of the Product class will look similar to this
using System;
using System.Collections.Generic;
using System.Text;

namespace Patterns
{
class Program
{
static void Main(string[] args)
{
Product myProduct = new Product();
myProduct.OnStateChange += new StateChangeHandler(myProduct_OnStateChange);
myProduct.MyState = State.State3;
}

static void myProduct_OnStateChange(State newState)
{
Console.WriteLine("State changed to {0}", newState);
}
}
}
So now the Program class instantiates an object of type Product and registers itself in the OnStateChange event so whoever changes the MyState property of the object myProduct, the Program class gets notified.
I am not a Design Pattern Guru, however I think this implementation is more suitable for C# and makes use of the unique C# features that produces elegant code.
kick it on DotNetKicks.com
Published Saturday, March 10, 2007 6:04 PM by Mohammed Hossam
Filed Under: , ,

Comments

# re: Observer Pattern in C# = Events & delegates

Friday, March 30, 2007 4:40 PM by throwspoop
Good post. Simple easy to understand example!

# re: Observer Pattern in C# = Events & delegates

Saturday, April 28, 2007 8:16 AM by Greg Askew
Very good.  Perhaps you should explain why Notify() was written with two separate events.  The other way would be to write:
 
private void Notify()
{
   StateChangeHandler _onChange = OnStateChange
   if (_onChange != null)
   _onChange (_state);
}

This additional step of creating a local copy of the delegate ensures that if all subscribers were removed (by another thread) between the check for null and sending the notification, you will not throw a NullReferenceException.

# re: Observer Pattern in C# = Events & delegates

Sunday, December 02, 2007 7:50 AM by jerry
I'd been searching for simple explanation for a while - i now understand this topic. Well done for explaining it rather than over complicating it and trying to prove you can code well (which you obviously can) :)lol

# re: Observer Pattern in C# = Events & delegates

Friday, February 22, 2008 4:27 AM by laptrinhc97
I think it's very helpful. I have a question and hope that you will answer me  as soon as posible. Can you explanation how using this pattern in C# but with Windows Form. How to effect a changging in Main form make sub form will be changed.
Anonymous comments are disabled