Wednesday, October 30, 2024

Delegate and Event, Additional FAQs

Question1

Delegate is a type in C#. Delegate and event are closely related. Is event is a type in C#?

Yes, in C#, an event is technically a member, not a type itself. It acts as a special form of delegate, providing a way to encapsulate a delegate and control how it’s accessed from outside the containing class.

Here’s how event and delegate are related and how they differ:

Delegate: A delegate is a type that represents references to methods with a specific signature. Delegates allow methods to be passed as parameters or assigned to variables, enabling callback functions and event handling.

public delegate void Notify();  // Declaring a delegate type
Event: An event is a keyword that works with a delegate to provide a publisher-subscriber model. The event keyword restricts direct access to the delegate, so only the declaring class can invoke it, while other classes can only add or remove event handlers. This encapsulation helps protect the delegate's invocation list.

public class Process
{
    public event Notify ProcessCompleted;  // Declaring an event
}

In summary:
  1. Delegate is a type in C#.
  2. Event is not a type, but it relies on a delegate type to work as an event member, controlling the access and providing encapsulation for invoking delegate methods.

Question2

Is event a member of class?

Yes, an event is indeed a member of a class (or struct). In C#, events are special members that enable classes to provide notifications to other parts of the application.

When an event is declared in a class, it typically follows these guidelines:
  • Encapsulation: The class containing the event (the publisher) has full control over when the event is triggered (raised). However, outside classes (subscribers) can only subscribe to or unsubscribe from the event, not invoke it directly.
  • Delegate-based: An event is associated with a specific delegate type. The delegate defines the signature of methods that can be attached to the event.
Here’s a simple example of an event as a class member:

public delegate void Notify();  // Declare a delegate type

public class Process
{
    public event Notify ProcessCompleted;  // Declare an event as a member

    public void StartProcess()
    {
        // Process logic here
        OnProcessCompleted();  // Raise the event when processing is complete
    }

    protected virtual void OnProcessCompleted()
    {
        ProcessCompleted?.Invoke();  // Safely invoke the event
    }
}
In this example:

  • ProcessCompleted is an event member of the Process class.
  • The StartProcess method raises the event using the OnProcessCompleted method.
  • So, events in C# act as members, enabling encapsulated delegate invocation within the class while allowing outside objects to subscribe/unsubscribe to notifications.

Question3

In C#, properties and methods are considered as members of a class. So, an event is what kind of member of the class?

In C#, an event is considered a member of a class, specifically categorized as a type of specialized delegate member. Like fields, properties, and methods, events provide a way for a class to encapsulate functionality. However, an event has a unique role—it’s specifically designed for the publisher-subscriber pattern to handle notifications.

Here's how events fit among other class members:
  1. Field: Stores data directly.
  2. Property: Provides controlled access to a field.
  3. Method: Encapsulates a block of code that performs an action.
  4. Event: Manages a delegate invocation list that allows other classes to subscribe to and handle notifications.

Why Events Are Unique
  • An event is built on a delegate type but adds additional encapsulation by controlling access:
  • Subscribers can only add or remove handlers; they cannot directly invoke the event.
  • The class that declares the event has the exclusive right to raise (invoke) the event, making it safer for the publisher-subscriber scenario.
Example
Here’s an example to illustrate how an event serves as a specialized member:

public delegate void Notify();  // Define a delegate

public class Process
{
    public event Notify ProcessCompleted;  // Event member

    public void Start()
    {
        // Logic here
        OnProcessCompleted();
    }

    protected virtual void OnProcessCompleted()
    {
        ProcessCompleted?.Invoke();  // Raise the event
    }
}
Summary
  • An event in C# is a specialized member that:
  • Is built on top of a delegate type.
  • Acts as a notification mechanism within the class.
  • Controls access, ensuring only the declaring class can invoke it, while others can subscribe/unsubscribe.
  • This encapsulation makes events unique as a type of delegate-based member in C#.

Question4

An event is defined in one class, Publisher, then how that event is consumed in another class?
To consume an event in another class, the "subscriber" class needs to subscribe to the event defined in the "publisher" class. This is done by creating an instance of the publisher, attaching an event handler method to the event, and defining what should happen when the event is raised.

Here’s a step-by-step example to illustrate:

Step 1: Define the Event in the Publisher Class
The publisher class declares an event and raises it at appropriate times:

// Define a delegate that specifies the signature of the event handler
public delegate void NotifyEventHandler(string message);

public class Publisher
{
    // Declare an event using the delegate type
    public event NotifyEventHandler Notify;

    public void StartProcess()
    {
        Console.WriteLine("Process Started...");
        
        // Raise the event when the process completes
        OnNotify("Process Completed!");
    }

    // Protected virtual method to raise the event
    protected virtual void OnNotify(string message)
    {
        // Check if there are any subscribers
        Notify?.Invoke(message);
    }
}

Step 2: Subscribe to the Event in the Subscriber Class
In the subscriber class, you create an instance of the publisher class, define an event handler, and subscribe to the event.

public class Subscriber
{
    // Event handler method that matches the delegate signature
    public void OnProcessCompleted(string message)
    {
        Console.WriteLine("Subscriber received notification: " + message);
    }

    public void Subscribe(Publisher publisher)
    {
        // Subscribe to the event
        publisher.Notify += OnProcessCompleted;
    }

    public void Unsubscribe(Publisher publisher)
    {
        // Unsubscribe from the event
        publisher.Notify -= OnProcessCompleted;
    }
}

Step 3: Instantiate the Classes and Trigger the Event
The main program creates instances of the Publisher and Subscriber classes, subscribes to the event, and triggers it by calling the publisher's method.

public class Program
{
    public static void Main()
    {
        Publisher publisher = new Publisher();  // Create publisher instance
        Subscriber subscriber = new Subscriber();  // Create subscriber instance

        subscriber.Subscribe(publisher);  // Subscribe to the event
        
        publisher.StartProcess();  // Start the process, which will raise the event

        subscriber.Unsubscribe(publisher);  // Optional: Unsubscribe if needed
    }
}

Output
arduino
Process Started...
Subscriber received notification: Process Completed!

Explanation
  1. Define the Event: In the Publisher class, the Notify event is declared and raised when StartProcess completes.
  2. Handle the Event: The Subscriber class defines a method, OnProcessCompleted, which matches the event’s delegate signature and acts as the event handler.
  3. Subscribe: The subscriber subscribes to the event by attaching OnProcessCompleted to publisher.Notify.
  4. Trigger the Event: When StartProcess is called, it raises the Notify event, which invokes OnProcessCompleted in the Subscriber.
  5. This model provides a loose coupling between Publisher and Subscriber, allowing them to communicate through the event without being tightly bound.

Related Post

No comments:

Post a Comment

Hot Topics