Introduction
This article provides a real world usage example of using delegates. What is a delegate, and how do I use it in my code? Think of a delegate as a thread safe pointer, providing a thread throughput to a method call on a class. I have seen a lot of theoretical examples on how to use delegates, but to get more people to use them I have created a real world example that was created as part of my professional work.
Background
I need a way to provide a thread safe pointer from a child object to a parent object, without putting the parent object in the child object as a parameter, which would cause a circular reference. I wanted to change a parameter on the parent object when the child object was changed, without having to reference the parent object directly. The solution I came up with was to use a delegate. The delegate allowed me to provide a pointer in the child object to its parent, without having to directly reference the parent.
Using the code
Notice that the parent object contains the child object:
public class ParentObject
{
private ChangeType _changeType = ChangeType.None;
private ChildObject _childObject;
Notice that the child object does not contain the parent, but instead two delegate types ParentSetChangeTypeDelegate
and ParentGetChangeTypeDelegate
:
public class ChildObject
{
#region Private Varaibles
private ChangeType _changeType = ChangeType.None;
private ParentSetChangeTypeDelegate _parentSetChangeTypeDelegate;
private ParentGetChangeTypeDelegate _parentGetChangeTypeDelegate;
#endregion
We have two constructors one that has no parameters, and one that accepts the ParentObject
class. This provides a control for supporting the object alone or within its parent:
#region Constructor
public ChildObject()
{
}
public ChildObject(ParentObject parent)
{
SetParent(parent);
}
#endregion
The SetParent
method provides a way to set up the accessors to the methods on the parent class. Notice the way we delegate the method calls from the parent class to the child. In this fashion we can provide a thread safe pointer back to the parent class, without having the parent as an actual parameter:
public void SetParent(ParentObject parent)
{
if(parent != null)
{
_parentGetChangeTypeDelegate =
new ParentGetChangeTypeDelegate(parent.GetTypeOfChange);
_parentSetChangeTypeDelegate =
new ParentSetChangeTypeDelegate(parent.SetTypeOfChange);
}
}
The DoChange
method actually makes changes to the child and parent object via the delegates:
public void DoChange(ChangeType changeType)
{
if(_parentGetChangeTypeDelegate != null &&
_parentSetChangeTypeDelegate != null)
{
switch(changeType)
{
case ChangeType.Add :
SetTypeOfChange(ChangeType.Add);
_parentSetChangeTypeDelegate(ChangeType.Modify);
break;
case ChangeType.Modify :
SetTypeOfChange(ChangeType.Modify);
_parentSetChangeTypeDelegate(ChangeType.Modify);
break;
case ChangeType.Remove :
SetTypeOfChange(ChangeType.Remove);
_parentSetChangeTypeDelegate(ChangeType.Modify);
break;
default :
break;
}
}
Notice when the child changes, the value of GetTypeOfChange
on the parent object will change as well.
line 30: Console.WriteLine("///New Change....///");
line 32: child.DoChange(ChangeType.Add);
Points of interest
Run the test, and see for yourself how it works. I hope this helps someone who has had trouble finding a real world example on how to use delegates.
History
This is the first submission to CodeProject on this subject and is the first revision.