Reader Level:
ARTICLE

Implementing Delegates in C# : Part 2

Posted by TimothyA Vanover Articles | C# Language February 13, 2001
This is second part of Timothy's Delegates in C# series...
  • 0
  • 0
  • 20354
Download Files:
 

This is the second in a series of project for using Delegates. The next few articles submitted will get a bit more complex and will be modeled after this one to help get people familiar with what is being accomplished. This is a brief description of the following project for this article.

For the example listed we have two base classes with virtual methods. The two base classes have classes, which are derived. We also have a class containing a delegate. The following example shows the objects and their derived classes.

The Employees Class contains:

Management 
Virtual method container
Developers
Virtual method container
Company 
Delegate 
contatiner
Managers : Management
Overloads constructor and Virtual method
AssociateConsultants : 
Developers
Overloads constructor
and
Virtual method

SaleStaff : Management
Overloads constructor and
Virtual method

Consultants : Developers
Overloads constructor and Virtual method
Executives : Management Overloads constructor and Virtual method SeniorConsultants : Developers Overloads constructor and Virtual method

The base and derived classes have a method that returns a string. Consider that in an organization you will have different types of employees. Some of the types of employees might fall into groups or have similar functions within the organization. For the sake of understanding I used an office-meeting message that would be sent to different entities within an organization. Each of these derives from either the Management group or the Development group.  

In the example I used a class instead of an interface. There are benefits and drawbacks to this. A benefit is that I can call the base class method from a derived class if I desire to do so or even instantiate the base class as long as it is not declared as an abstract class. Notice the following two examples containing the Meeting method for the base class and one of the derived classes. 

Base method

public virtual string Meeting ( )
{
DateTime time = DateTime.Today;
return time.ToString();
}

Derived Method

public override string Meeting()
{
return this.meetingDate;


There is a bit more overhead associated with this type of association. I could have more efficiently used and interface which has only method descriptions with no implementation of code inside the methods. This would not allow the base instantiation or base method to have its own unique method return value inside the inherited class. 

Inside Main of the Employees class I have created an instance of the derived classes and assigned a meeting date to each object. 

public static void Main()
{
SalesStaff objSales =
new SalesStaff("02/15/2001");
Managers objManagers =
new Managers("02/16/2001");
Executives objExec =
new Executives("02/17/2001");
AssociateConsultants objAssocCon =
new AssociateConsultants("02/20/2001"); Consultants objCon = new Consultants("02/21/2001");
SeniorConsultants objSenCon =
new SeniorConsultants("03/22/2001");
object[] employees = {
objSales, objManagers, objExec, objAssocCon, objCon, objSenCon };
//method which calls methods on the objects contained in the array of objects
SendNotices(employees);


I have then put each of the objects in an object array as a container to send to a function to make a call through the delegate based on the base type.  For this example we are going to send a message of an office meeting based on the type of employee group. In the next article I will add events to this, but we are going to do simple methods for this article. The SendNotices method takes an object array and determines the base type of the objects contained in each of the array indices.  Youll notice that we are attempting to cast with the as operator. 

public static void SendNotices(params object[] arr)
{
//for aech item in the array cast it as the base
foreach(object o in arr)
{
Management management = o
as Management;
//if the item does not have a base class of Management NULL is
//returned and the delegate call is not made
if(management != null)
MessageBox.Show(CallMeeting(management));
}
}

If the conversion fails a null is returned instead of the type of the expected type. We then check the object for null and call the CallMeeting method. 

public static string CallMeeting(Management management)
{
Company comp =
new Company();
//create a new delegate from the class and instantaite it to call
//this base class.Method
Company.SendMemo Meeting = new Company.SendMemo(management.Meeting);
return(comp.Announcement(Meeting));
}

This method creates an instance of the class Company, which contains our delegate functionality.  Below is the class, which contains a delegate string named SendMemo and a string named Announcement method. The Announcement method takes the SendMemo as a type in the parameter list for the method, and returns the instance Action. In reality this is an action, as the delegate will call a method as a sort of function pointer to a method. The difference is that this is not an actual function pointer. With System.Delegate an instance of an object with the same method signature can be called. 

public class Company
{
public delegate string SendMemo();
public string Announcement(SendMemo Action)
{
return Action() ;
}
}

The output of this call will be 3 message boxes for the instances of the derived classes, which have the base type of Management.

In the next article I am intending on building on this example and adding Events to the mix. Hope this has been useful and informative.

COMMENT USING