A delegate in C# is a type that represents references to methods with a particular parameter list and return type. Delegates are close to C++ function pointers but are object-oriented, type-safe, and secure.
Delegates allow methods to be passed as parameters, enabling flexible designs and dynamic behavior. They are useful for:
Declaration: Declare the delegate type with a return type and parameters.
Instantiation: Create an instance of the delegate, which points to a specific method.
Invocation: Invoke the method through the delegate.
Multicasting: A delegate can point to multiple methods.
To declare a delegate, use the delegate
keyword followed by the signature of the method.
public delegate int MyDelegate(int x, int y);
In the above example, MyDelegate
can point to any method with two int
parameters and returns an int
.
Declare and instantiate the delegate, then assign a target method to it.
public class Operations { public int Add(int a, int b) => a + b; public int Multiply(int a, int b) => a * b; } class Program { static void Main() { Operations operations = new Operations(); MyDelegate del = new MyDelegate(operations.Add); int result = del(10, 20); Console.WriteLine(result); // Output: 30 } }
A multicast delegate can refer to more than one method. Use +=
to attach methods and -=
to detach them.
MyDelegate del = operations.Add; del += operations.Multiply; int result = del(10, 20); Console.WriteLine(result); // Output may vary depending on method resolution order.
Func: Delegate that returns a value.
Funcadd = (a, b) => a + b; int sum = add(5, 10); // Output: 15
Action: Does not return a value.
Actiongreet = name => Console.WriteLine("Hello, " + name); greet("World"); // Output: Hello, World
Predicate: Returns a boolean value.
PredicateisPositive = x => x > 0; bool result = isPositive(10); // Output: true
Events in C# use delegates to handle notifications in event-driven programs.
public class Publisher { public delegate void Notify(); public event Notify OnPublish; public void Publish() { Console.WriteLine("Publishing an event."); OnPublish?.Invoke(); } } public class Subscriber { public void OnNotified() { Console.WriteLine("Subscriber notified!"); } } class Program { static void Main() { Publisher pub = new Publisher(); Subscriber sub = new Subscriber(); pub.OnPublish += sub.OnNotified; pub.Publish(); // Output: // Publishing an event. // Subscriber notified! } }
Loose Coupling: Offers flexibility and modularity.
Event Handling: Essential for implementing events and subscribers.
Multithreading: Methods like BeginInvoke
facilitate asynchronous processing.
Func
, Action
, Predicate
) simplify delegate usage.