Delegate Basic

An interesting and useful property of a delegate is that it does not know or care about the class of the object that it references. Any object will do; all that matters is that the method’s argument types and return type match the delegate’s. This makes delegates perfectly suited for “anonymous” invocation.

The signature of a single cast delegate is shown below:

delegate result-type identifier ([parameters]);

where:

  • result-type: The result type, which matches the return type of the function.
  • identifier: The delegate name.
  • parameters: The Parameters, that the function takes.

Examples:

public delegate void SimpleDelegate ()

This declaration defines a delegate named SimpleDelegate, which will encapsulate any method that takes
no parameters and returns no value.

public delegate int ButtonClickHandler (object obj1, object obj2)

This declaration defines a delegate named ButtonClickHandler, which will encapsulate any method that takes
two objects as parameters and returns an int.

A delegate will allow us to specify what the function we’ll be calling looks like without having to specify which function to call. The declaration for a delegate looks just like the declaration for a function, except that in this case, we’re declaring the signature of functions that this delegate can reference.

There are three steps in defining and using delegates:

  • Declaration
  • Instantiation
  • Invocation

A very basic example (SimpleDelegate1.cs):

using System;

namespace Akadia.BasicDelegate
{
// Declaration
public delegate void SimpleDelegate();

class TestDelegate
{
public static void MyFunc()
{
Console.WriteLine(“I was called by delegate …”);
}

public static void Main()
{
// Instantiation
SimpleDelegate simpleDelegate = new SimpleDelegate(MyFunc);

// Invocation
simpleDelegate();
}
}
}

Compile an test:

# csc SimpleDelegate1.cs
# SimpleDelegate1.exe
I was called by delegate …

Calling Static Functions

For our next, more advanced example (SimpleDelegate2.cs), declares a delegate that takes a single string parameter and has no return type:

using System;

namespace Akadia.SimpleDelegate
{
// Delegate Specification
public class MyClass
{
// Declare a delegate that takes a single string parameter
// and has no return type.

public delegate void LogHandler(string message);

// The use of the delegate is just like calling a function directly,
// though we need to add a check to see if the delegate is null
// (that is, not pointing to a function) before calling the function.

public void Process(LogHandler logHandler)
{
if (logHandler != null)
{
logHandler(“Process() begin”);
}

if (logHandler != null)
{
logHandler (“Process() end”);
}
}
}

// Test Application to use the defined Delegate
public class TestApplication
{
// Static Function: To which is used in the Delegate. To call the Process()
// function, we need to declare a logging function: Logger() that matches
// the signature of the delegate.

static void Logger(string s)
{
Console.WriteLine(s);
}

static void Main(string[] args)
{
MyClass myClass = new MyClass();

// Crate an instance of the delegate, pointing to the logging function.
// This delegate will then be passed to the Process() function.

MyClass.LogHandler myLogger = new MyClass.LogHandler(Logger);
myClass.Process(myLogger);
}
}
}

Compile an test:

# csc SimpleDelegate2.cs
# SimpleDelegate2.exe
Process() begin
Process() end

Calling Member Functions

In the simple example above, the Logger( ) function merely writes the string out. A different function might want to log the information to a file, but to do this, the function needs to know what file to write the information to (SimpleDelegate3.cs)

using System;
using System.IO;

namespace Akadia.SimpleDelegate
{
// Delegate Specification
public class MyClass
{
// Declare a delegate that takes a single string parameter
// and has no return type.

public delegate void LogHandler(string message);

// The use of the delegate is just like calling a function directly,
// though we need to add a check to see if the delegate is null
// (that is, not pointing to a function) before calling the function.

public void Process(LogHandler logHandler)
{
if (logHandler != null)
{
logHandler(“Process() begin”);
}

if (logHandler != null)
{
logHandler (“Process() end”);
}
}
}

// The FileLogger class merely encapsulates the file I/O
public class FileLogger
{
FileStream fileStream;
StreamWriter streamWriter;

// Constructor
public FileLogger(string filename)
{
fileStream = new FileStream(filename, FileMode.Create);
streamWriter = new StreamWriter(fileStream);
}

// Member Function which is used in the Delegate
public void Logger(string s)
{
streamWriter.WriteLine(s);
}

public void Close()
{
streamWriter.Close();
fileStream.Close();
}
}

// Main() is modified so that the delegate points to the Logger()
// function on the fl instance of a FileLogger. When this delegate
// is invoked from Process(), the member function is called and
// the string is logged to the appropriate file.

public class TestApplication
{
static void Main(string[] args)
{
FileLogger fl = new FileLogger(“process.log”);

MyClass myClass = new MyClass();

// Crate an instance of the delegate, pointing to the Logger()
// function on the fl instance of a FileLogger.

MyClass.LogHandler myLogger = new MyClass.LogHandler(fl.Logger);
myClass.Process(myLogger);
fl.Close();
}
}
}

The cool part here is that we didn’t have to change the Process() function; the code to all the delegate is the same regardless of whether it refers to a static or member function.

Compile an test:

# csc SimpleDelegate3.cs
# SimpleDelegate3.exe
# cat process.log
Process() begin
Process() end

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: