;

C# Single-Cast Delegate


Single-cast delegates in C# allow you to encapsulate a single method with a specific signature, making them a powerful feature for dynamic method invocation. This guide will walk you through the basics of single-cast delegates, provide examples, discuss their use cases, and show you how they’re applied in real-world scenarios.

Introduction to Single-cast Delegates

A single-cast delegate in C# is a delegate that references one method at a time. A delegate acts as a type-safe function pointer, meaning it can only point to methods that have the same signature as defined by the delegate. Single-cast delegates are useful for scenarios where you need a flexible way to invoke different methods without hardcoding them into your application logic.

Key Characteristics:

  • Single Method Reference: Can only point to one method at any given time.
  • Type-safe: Ensures that only methods with matching signatures are assigned.
  • Flexible Invocation: Provides a way to invoke a method dynamically at runtime.

Defining and Using a Single-cast Delegate

The basic syntax for defining a delegate is straightforward. You use the delegate keyword, specify a return type, and define the parameters that any assigned method should have.

Syntax

public delegate ReturnType DelegateName(ParameterList);

Example: Simple Single-cast Delegate

Here’s a basic example showing how to declare, instantiate, and use a single-cast delegate.

using System;

// Define a delegate that matches any method with a void return type and one string parameter
public delegate void NotifyDelegate(string message);

class Program
{
    // A method matching the delegate signature
    static void Greet(string message)
    {
        Console.WriteLine("Message: " + message);
    }

    static void Main()
    {
        // Create an instance of the delegate and assign the method
        NotifyDelegate notify = Greet;

        // Invoke the delegate
        notify("Hello, Single-cast Delegate!");
    }
}

Explanation

  • NotifyDelegate: A delegate type that points to methods with a void return type and a string parameter.
  • Greet: A method that matches the delegate signature.
  • Instantiation: The notify delegate is assigned the Greet method, allowing us to call Greet using notify.

Example: Single-cast Delegate in Action

Let's explore a more advanced example where a single-cast delegate is used to apply different discount calculations. Here, we’ll define a delegate that can reference different discount methods, allowing dynamic selection at runtime.

using System;

// Define a delegate for discount calculation
public delegate decimal DiscountDelegate(decimal price);

class DiscountCalculator
{
    // Method for standard discount
    public static decimal StandardDiscount(decimal price) => price * 0.90M; // 10% off

    // Method for premium discount
    public static decimal PremiumDiscount(decimal price) => price * 0.80M; // 20% off
}

class Program
{
    static void Main()
    {
        DiscountDelegate discount;

        // Assigning Standard Discount to delegate
        discount = DiscountCalculator.StandardDiscount;
        Console.WriteLine("Standard Discount on $100: " + discount(100)); // Outputs $90

        // Assigning Premium Discount to delegate
        discount = DiscountCalculator.PremiumDiscount;
        Console.WriteLine("Premium Discount on $100: " + discount(100)); // Outputs $80
    }
}

Explanation

  • DiscountDelegate: A delegate that points to methods with a decimal return type and a decimal parameter.
  • StandardDiscount & PremiumDiscount: Methods to calculate different discounts based on the delegate.
  • Dynamic Assignment: The discount delegate can be dynamically assigned to point to either discount method, demonstrating flexible code based on runtime decisions.

Use Case: This example is useful in systems that need dynamic discount application based on customer status or promotional events.

Real-World Example: Callback in a Payment System

In an e-commerce system, we often need a callback to notify users when a payment is complete. Using a single-cast delegate, we can set up a method to execute as a callback after the payment process.

using System;

public delegate void PaymentCallback(string status);

class PaymentProcessor
{
    // Method simulating a payment process and triggering a callback
    public void ProcessPayment(PaymentCallback callback)
    {
        Console.WriteLine("Processing Payment...");
        System.Threading.Thread.Sleep(2000); // Simulate delay
        
        // Call the delegate after payment processing
        callback("Payment Successful");
    }
}

class Program
{
    // Notification method matching the delegate
    static void NotifyUser(string status)
    {
        Console.WriteLine("User Notification: " + status);
    }

    static void Main()
    {
        PaymentProcessor processor = new PaymentProcessor();
        PaymentCallback callback = NotifyUser; // Assign NotifyUser method to delegate
        
        processor.ProcessPayment(callback);
    }
}

Explanation

  • PaymentCallback: A delegate used as a callback, matching methods with void return type and a single string parameter.
  • ProcessPayment: A method that simulates a payment process and triggers the callback.
  • NotifyUser: A method that matches the delegate signature, serving as the notification mechanism.

Real-World Use Case: This is a typical pattern in payment systems, where a callback is needed to confirm payment completion or failure to a user.

Key Takeaways

  • Method Flexibility: Single-cast delegates provide a way to store and invoke methods dynamically, making them adaptable to different runtime needs.
  • Single Invocation: Unlike multi-cast delegates, single-cast delegates hold a reference to only one method, making them simpler to understand and use.
  • Ideal for Callbacks: Single-cast delegates are well-suited for scenarios that require a callback mechanism, such as notifying users after a process completes.
  • Encapsulation of Functionality: Delegates help encapsulate method logic within a delegate, reducing the need for rigid hardcoding.

Summary

Single-cast delegates in C# are a type-safe, powerful mechanism for referencing a single method, making it possible to invoke methods flexibly and dynamically. They simplify code by removing the need for hardcoded method calls, instead allowing you to assign and invoke methods at runtime. In real-world applications, they are frequently used in callback scenarios, such as confirming a successful payment or notifying users of certain events. With single-cast delegates, C# provides a robust tool for writing flexible, modular, and dynamic code.