Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Delegates for Dummies

0.00/5 (No votes)
16 Oct 2007 1  
Primer - The basics about delegates, how to define them and use them

Introduction

Delegates are a concept that for some reason are always confusing. I still have to Google delegates every time I want to use them to get the syntax correct. Let's see if we can dumb down delegates to something a bit more understandable. This is a primer article that is very, very basic, it doesn't even get into talking about events. There are a lot of articles out there that explain Delegates and Events, but I think that a lot of people are lost reading these articles because you need to understand the basics first. This is my crack at the basics, I hope this helps as this is a difficult topic to explain.

Definition: Delegate "a person designated to act for or represent another or others"

// Define a new type in the system called MathFunction
private delegate int MathFunction( int n1, int n2 );

// Create a variable of type MathFunction, the type MathFunction has been defined above.
private MathFunction adderFunction;

A delegate is a variable that holds a function. It's that simple, I can define a variable of type MathFunction and assign it one of my functions, then later instead of calling a specific function I can use the variable like a function and it will call the function that it was assigned earlier.

There are many types that can be used when declaring a variable. int, string and boolean are some of the native types that can be used. Developers can define their own types by defining Classes, Delegates, Enums and Structs in their code. Above we defined a new Delegate Type called MathFunction. We can now use this type when declaring variables. In the code example above, we create a variable called adderFunction which is of type MathFunction. The Type MathFunction is a delegate, which means that it can be used like a function and when executed it will call a specific function on that function's behalf. Getting back to the original definition of a delegate: "a variable designed to act for a function".

Using the Code

// Define a new type in the system called MathFunction
private delegate int MathFunction( int n1, int n2 );

// Declare a variable that will hold a function of type MathFunction.
private MathFunction adderFunction;

static void Main()
{         
   // Assign the real function Add() to the variable adderFunction
   adderFunction = Add;

   // Call whatever function has been stored in the variable adderFunction
   int res = adderFunction( 1, 2 );
}

// This function matches exactly the signature defined in the MathFunction type
private int Add( int n1, int n2 )
{
   return n1 + n2;
}

We've created a new Type in the system called MathFunction, we used this type to declare a variable called adderFunction. This variable is assigned the function Add. The variable adderFunction can be called like a function adderFunction(5, 10); and it will call the real function Add.

A function can differ in its return type, its number of arguments and the types of those arguments. We defined the delegate type MathFunction to specifically state that a variable declared of this type can be used like a function that takes two int arguments and returns a type int. Now that we have defined the signature (or prototype) of the function that this variable can hold, we can now assign the variable a real function that matches exactly that signature.

Real World Example

Have you ever written a function that does a bunch of stuff, then something specific, then a bunch of stuff again. Now Copy and Paste that function 5 times and change only those 3 or 4 lines of specific code in the middle... Wouldn't it be nice if you could, as an argument, pass in a few lines of code then have only one function that did all the overhead stuff but ran those of 4 lines of specific code in the middle??? This is a textbook example for delegates.

For example, when you are talking with a Web server you have a lot of overhead before and after the actual Web call, like logging, timings, handling errors, etc. The MakeWebCall() function implements all of this overhead, but you need to run 3 or 4 lines of specific code to parse the response. Yes, there's other ways of doing this w/o delegates... Rather than copy and paste this function for each type of server call you need to issue, handle this problem by adding an argument to the MakeWebCall function that is a delegate. This delegate takes in the HttpWebResponse object, performs its specific parsing logic and then returns a string (or maybe raises an error). See the code below:

private delegate string dgProcessResponse( HttpWebResponse response );

// ----------------------------------- Below we pass in the delegate function.
private string MakeWebCall( string url, dgProcessResponse ProcessResponseFunction )
{
   string sResponse = String.Empty;
   try
   {
      // Setup logging
      // Setup Timing
      // Setup Web Request object

      // Call the Server
      HttpWebRequest req = WebRequest.Create( url ) as HttpWebRequest;
      HttpWebResponse response = req.GetResponse() as HttpWebResponse;

      // Always check that your delegate isn't null!
      if( ProcessResponseFunction != null )
      {
         sResponse = ProcessResponseFunction( response );  // <--- USE THE DELEGATE
      }
   }
   catch( Exception ex )
   {
      // Handle errors
      // Handle recoverable Logon Errors
   }
   finally
   {
      // End Timings
      // End Logon
   }
   return sResponse;
}

Points of Interest

Andrew D. Weiss
Software Engineer

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here