Delegates in C# can invoke multiple methods in sequence, known as multicast delegation. This feature is beneficial when you need several actions triggered by a single event, improving modular code design.
using System;// Define a delegate typepublic delegate void Notify();class Program{static void Main(){// Instantiate the delegateNotify notifyAll = Alert1;notifyAll += Alert2; // Multicast: Add another method// Invokes both Alert1 and Alert2notifyAll();}static void Alert1(){Console.WriteLine("Alert 1 called!");}static void Alert2(){Console.WriteLine("Alert 2 called!");}}
In C#, the Action
and Func
types are built-in delegates for defining common method signatures in a simplified manner. Action
is used for methods without a return value, while Func
is for methods with a return value.
// Action delegate exampleAction printHello = () => Console.WriteLine("Hello, World!");printHello();// Func delegate exampleFunc<int, int, int> add = (a, b) => a + b;int result = add(5, 3);Console.WriteLine(result);
delegate
UsageA delegate in C# is a type that references a method. Use delegate
to encapsulate a method signature for a specific parameter list and return type. This allows methods to be passed as parameters.
public delegate void MessageDelegate(string message);public void ShowMessage(string msg) {Console.WriteLine(msg);}// UsageMessageDelegate del = ShowMessage;del("Hello, World!");
Delegates in C# act as type-safe references to methods, enabling encapsulation and callbacks. They delegate the responsibility of executing methods to other code blocks, thus promoting flexibility and reusability in code design.
using System;public delegate void ShowMessage(string message);public class Program{static void DisplayMessage(string message){Console.WriteLine(message);}public static void Main(){ShowMessage showMessageDelegate = DisplayMessage;showMessageDelegate("Hello from the delegate!");}}
C# provides a concise way to create delegate instances using lambda expressions and expression-bodied members. This syntax simplifies the way you write methods and functions by using the =>
(lambda) operator. This can make your code more readable and maintainable.
using System;class Program{static void Main(){Func<int, int> square = x => x * x;Console.WriteLine(square(5)); // Outputs: 25}}
Predicate
DelegatesPredicate
delegates in C# are used for filtering data. They return a boolean value, typically indicating whether an object matches a specific condition. This makes them handy in methods like FindAll()
to filter collections efficiently.
List<int> numbers = new List<int>{ 1, 3, 5, 6, 7, 8, 10 };Predicate<int> isEven = x => x % 2 == 0;List<int> evenNumbers = numbers.FindAll(isEven);Console.WriteLine(string.Join(", ", evenNumbers));// Output: 6, 8, 10
delegate
MethodsIn C#, delegate
can be associated with both instance methods and static methods through method group conversion. This allows for flexible referencing and calls to methods dynamically at runtime, enhancing reusability.
using System;public class Example {public delegate void PrintDelegate(string message);// Static methodpublic static void PrintStatic(string message) {Console.WriteLine("Static: " + message);}// Instance methodpublic void PrintInstance(string message) {Console.WriteLine("Instance: " + message);}public static void Main() {Example example = new Example();// Referencing static methodPrintDelegate printStatic = PrintStatic;printStatic("Hello from static method");// Referencing instance methodPrintDelegate printInstance = example.PrintInstance;printInstance("Hello from instance method");}}
C# lambda expressions provide a concise way to create anonymous functions. They can capture variables from their surrounding scope, making them powerful when used with delegates. In the example, notice how the threshold
variable, defined in the enclosing scope, is used within the lambda.
using System;class Program{static void Main(){int threshold = 10;Func<int, bool> isAboveThreshold = number => number > threshold;Console.WriteLine(isAboveThreshold(15)); // Outputs: TrueConsole.WriteLine(isAboveThreshold(5)); // Outputs: False}}