Introduction
In C#, a delegate is a type that represents a method with a specific signature. A delegate is similar to a function pointer in C or C++, but is type-safe and can be used with C#'s object-oriented features. Delegates are used to pass methods as arguments to other methods, and can be used to implement events and callbacks.
Implementing with delegates
// Define the delegate for the event
delegate void MyEventHandler(string message);
// Define a class that will raise the event
class EventPublisher {
// Declare the event using the delegate
public event MyEventHandler MyEvent;
// Method to raise the event
public void RaiseEvent(string message) {
if (MyEvent != null) {
MyEvent(message);
}
}
}
// Define a class that will subscribe to the event
class EventSubscriber {
public void HandleEvent(string message) {
Console.WriteLine("Received message: " + message);
}
}
class Program {
static void Main(string[] args) {
// Create an instance of the publisher
EventPublisher publisher = new EventPublisher();
// Create an instance of the subscriber
EventSubscriber subscriber = new EventSubscriber();
// Subscribe the subscriber's method to the publisher's event
publisher.MyEvent += subscriber.HandleEvent;
// Raise the event
publisher.RaiseEvent("Hello World!");
//Output : Received message: Hello World!
}
}
In this example, we defined a delegate named MyEventHandler
that represents a method with a single string parameter. Then we define a class EventPublisher
that has a public event MyEvent
of type MyEventHandler
, and a method RaiseEvent
that raises the event by calling the delegate and passing a message. Then we defined a class EventSubscriber
that has a method HandleEvent
that will be called when the event is raised.
In the Main method, we create an instance of the publisher and subscriber, then we subscribe the subscriber's method to the publisher's event using the +=
operator. Next, we raise the event by calling the RaiseEvent
method on the publisher and passing a message as an argument. The subscriber's HandleEvent
method will be called and will print the message to the console.
This example demonstrates how events can be implemented using delegates in C#, The publisher and subscriber classes are completely decoupled and can be reused in other parts of the program. This allows for more flexible and dynamic programming.
Implementing without delegates
// Define the event argument class
class MyEventArgs: EventArgs {
public string Message {
get;
set;
}
}
// Define a class that will raise the event
class EventPublisher {
// Declare the event
public event EventHandler < MyEventArgs > MyEvent;
// Method to raise the event
public void RaiseEvent(string message) {
if (MyEvent != null) {
MyEvent(this, new MyEventArgs {
Message = message
});
}
}
}
// Define a class that will subscribe to the event
class EventSubscriber {
public void HandleEvent(object sender, MyEventArgs e) {
Console.WriteLine("Received message: " + e.Message);
}
}
class Program {
static void Main(string[] args) {
// Create an instance of the publisher
EventPublisher publisher = new EventPublisher();
// Create an instance of the subscriber
EventSubscriber subscriber = new EventSubscriber();
// Subscribe the subscriber's method to the publisher's event
publisher.MyEvent += subscriber.HandleEvent;
// Raise the event
publisher.RaiseEvent("Hello World!");
//Output : Received message: Hello World!
}
}
In this example, we defined a class MyEventArgs
that inherits from EventArgs
and has a property Message
. Then we defined a class EventPublisher
that has a public event MyEvent
of type EventHandler<MyEventArgs>
, and a method RaiseEvent
that raises the event by calling the event and passing a message. Then we defined a class EventSubscriber
that has a method HandleEvent
that will be called when the event is raised.
In the Main method, we create an instance of the publisher and subscriber, then we subscribe the subscriber's method to the publisher's event using the +=
operator. Next, we raise the event by calling the RaiseEvent
method on the publisher and passing a message as an argument. The subscriber's HandleEvent
method will be called and will print the message to the console.
As you can see, this program is quite similar to the previous one but instead of using the delegate, we use the built-in EventHandler<T>
and EventArgs
classes. This way of implementing events is also a common pattern in C#, and is more type-safe as it enforces the use of a specific event argument class.
Conclusion
In summary, using delegates provides more flexibility and control over the signature of the methods that can be used as event handlers, while not using them provides a more straightforward implementation with the use of built-in classes. Both approaches have their advantages and disadvantages, and the choice of which one to use will depend on the requirements of your application.
Here is a detailed article on C# Delegates and Events