A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked.
The signature of a single cast delegate is shown below:
delegate result-type identifier ([parameters]);
- result-type: The result type, which matches the return type of the function.
- identifier: The delegate name.
- parameters: The Parameters that the function takes.
Delegates allow a clearer separation of specification and implementation. A delegate specifies the signature of a method, and authors can write methods that are compatible with the delegate specification.
With multicast delegate, it is just like a normal delegate but it can point to multiple functions so on invocation of such delegate it will invoke all the methods and functions associated with the same one after another sequentially.
Events are wrapper around the delegate. It sits on top of the delegate and provides only the necessary encapsulation so that the destination objects can subscribe to the Event and not have full control on the delegate object.
Events are declared using delegates. The delegate object encapsulates a method so that it can be called anonymously. An event is a way for a class to allow clients to give it delegates to methods that should be called when the event occurs. When the event occurs, the delegate(s) given to it by its clients are invoked.
We will consider an example implementation of Logger application, which can be used to log messages in Console, File or Database etc.
We will declare a delegate named LogWriteDelegate which accepts one parameter named message.
public delegate void LogWriteDelegate(string message);
Next we will declare an Event of type LogWriteDelegate
public event LogWriteDelegate LogWriteEvent;
In our sample Logger the FileLogger and ConsoleLogger will subscribe or register to the above mentioned event so that when the Write method of logger is called the respective logic within the Write method of FileLogger and ConsolLogger will also gets invoked.
using (var logger = new Logger("testing", EntryType.Debug))
logger.LogWriteEvent += new Logger.LogWriteDelegate(consoleLogger.Write);
logger.LogWriteEvent += new Logger.LogWriteDelegate(fileLogger.Write);
You can notice here a multicast delegate; the LogWriteEvent is being registered with Console and File log write methods.
While firing an Event within the Logger object, it is always a good practice to check whether the event is registered or not.
public void Write()
if (LogWriteEvent != null)
Here the LogWriteEvent holds the address of the methods console.Write and fileLogger.Write. When firing an event it will sequentially call the respective methods which are pre-registered to this Event.
Note: The Logger application is designed in such a way that in future you can have multiple implementations of Loggers. Right now we have Console and File Logger; if you are interested in implementing a Database logger we can create a new Class named DatabaseLogger which will implement ILogger interface. Provide necessary Write method logic so that it will log messages to database.
Ones you have done with the DatabaseLogger implementation, you just have to create an instance and register the event as we have done for Console and File Loggers.