Built-in Delegates in C# – Easy Explanation with Examples

Introduction

Tired of writing long delegate definitions? 😡 Wish there was an easier way to use delegates in C#? Well, you’re in luck! πŸŽ‰

C# provides Built-in Delegates, which make life so much easier. You don’t need to declare custom delegates anymore. Just use the ready-made ones and save time!

By the end of this lesson, you’ll be a pro at using Built-in Delegates in C# with real-world examples! Let’s go! πŸš€

What Are Built-in Delegates in C#?

A delegate is just a reference to a method. But declaring delegates every time is boring. 😴

That’s why C# gives us three built-in delegates:

➑️ Action β†’ For methods that don’t return a value.
➑️ Func β†’ For methods that return a value.
➑️ Predicate β†’ For methods that return bool.

No need to write delegate definitions anymore! Just use these ready-made ones! πŸ₯³

Syntax of Built-in Delegates in C#

				
					Action<int> myAction;      // Stores a method with 1 int parameter, returns nothing
Func<int, string> myFunc;  // Stores a method with 1 int parameter, returns a string
Predicate<int> myPredicate; // Stores a method with 1 int parameter, returns bool
				
			

Example 1: Using Action Delegate

πŸ‘‰ Use Action<T> when you don’t need a return value.

πŸ’‘ Think of Action<T> like a messenger. It takes input, performs an action, but doesn’t return anything.

				
					using System;

class Program {
    static void PrintMessage(string msg) {
        Console.WriteLine(msg);
    }

    static void Main() {
        Action<string> action = PrintMessage; // Using Action delegate
        action("Hello from Action delegate!"); 
    }
}
				
			

πŸ“ Output:

				
					Hello from Action delegate!
				
			

πŸ”Ž Step-by-Step Explanation:

  1. Step 1: Declared an Action<string> delegate, which means it stores a method that takes a string and returns void.
  2. Step 2: Assigned the PrintMessage method to the action delegate.
  3. Step 3: Called action("Hello..."), which executed PrintMessage().

πŸ‘‰ Result? The message got printed! πŸŽ‰

Β 

πŸ“Œ Why Use Action<T>?

βœ… No need to define custom delegates. Saves time! ⏳
βœ… Makes code reusable. Just assign different methods when needed! πŸ”„
βœ… Perfect for logging, printing messages, notifications, etc. πŸ“’

Β 

πŸ“Œ Real-World Use Case?

Imagine a notification system where Action<string> is used to send alerts via Email, SMS, or Push Notification dynamically! πŸš€

Example 2: Using Func Delegate

πŸ‘‰ Use Func<T, TResult> when you need a return value.

πŸ’‘ Think of Func<T, TResult> like a calculator. It takes input, performs a calculation, and returns a result.

				
					using System;

class Program {
    static int DoubleNumber(int num) {
        return num * 2;
    }

    static void Main() {
        // βœ… Func delegate: Takes an int, returns an int
        Func<int, int> func = DoubleNumber;  
        
        // βœ… Calling the delegate and storing the result
        int result = func(10);  

        Console.WriteLine("Double of 10 is: " + result);
    }
}
				
			

πŸ“ Output:

				
					Double of 10 is: 20
				
			

πŸ”Ž Step-by-Step Explanation:

  1. Step 1: Declared a Func<int, int> delegate, which means it takes an int as input and returns an int as output.
  2. Step 2: Assigned the DoubleNumber method to the func delegate.
  3. Step 3: Called func(10), which executed DoubleNumber(10) and returned 20.
  4. Step 4: Printed the result.

πŸ‘‰ Result? The number got doubled! πŸŽ‰

Β 

πŸ“Œ Why Use Func<T, TResult>?

βœ… Eliminates the need for custom delegates. Saves time! ⏳
βœ… Perfect for mathematical operations, data transformations, filtering, etc. πŸ”’
βœ… Enhances code reusability & readability! πŸ“–

Β 

πŸ“Œ Real-World Use Case?

Imagine a discount calculator where Func<decimal, decimal> is used to calculate the final price after applying a discount dynamically! πŸš€

Example 3: Using Predicate Delegate

πŸ‘‰ Use Predicate<T> when you need a bool return value.

πŸ’‘ Think of Predicate<T> like a security check. It takes input, evaluates a condition, and returns true or false.

				
					using System;

class Program {
    static bool IsEven(int num) {
        return num % 2 == 0;
    }

    static void Main() {
        Predicate<int> predicate = IsEven; // Using Predicate delegate
        bool result = predicate(10);
        Console.WriteLine("Is 10 even? " + result);
    }
}
				
			

πŸ“ Output:

				
					Is 10 even? True
				
			

πŸ”Ž Step-by-Step Explanation:

  1. Step 1: Declared a Predicate<int> delegate, which means it takes an int as input and returns a bool as output.
  2. Step 2: Assigned the IsEven method to the predicate delegate.
  3. Step 3: Called predicate(10), which executed IsEven(10) and returned true.
  4. Step 4: Printed the result.

πŸ‘‰ Result? It correctly identified that 10 is even! πŸŽ‰

Β 

πŸ“Œ Why Use Predicate<T>?

βœ… Perfect for filtering data based on conditions!
βœ… Commonly used in List<T>.Find() and LINQ queries.
βœ… Enhances code reusability & readability!

Β 

πŸ“Œ Real-World Use Case?

Imagine a student grading system where Predicate<int> is used to check if a student has passed or failed based on a minimum score! πŸš€

Why Are Built-in Delegates Important?

βœ” They save time! No need to declare custom delegates.
βœ” They make code cleaner! Just use Action, Func, or Predicate.
βœ” They work well with LINQ and collections!

Real-World Example: Filtering a List πŸ“

Imagine you have a list of numbers, and you want to filter only even numbers. You can use Predicate<int> instead of writing long loops!

				
					using System;
using System.Collections.Generic;

class Program {
    static bool IsEven(int num) {
        return num % 2 == 0;
    }

    static void Main() {
        List<int> numbers = new List<int> {1, 2, 3, 4, 5, 6, 7, 8};
        
        List<int> evenNumbers = numbers.FindAll(IsEven);  // Using Predicate

        Console.WriteLine("Even numbers: " + string.Join(", ", evenNumbers));
    }
}
				
			

πŸ“ Output:

				
					Even numbers: 2, 4, 6, 8
				
			

πŸ”Ž Explanation:

βœ” FindAll(IsEven) filters only even numbers.
βœ” No need to write long loops! πŸš€

Another Example: Logging Messages πŸ“œ

Use Action<string> to log messages without repeating code!

				
					using System;

class Logger {
    public static void Log(string message) {
        Console.WriteLine("[LOG]: " + message);
    }
}

class Program {
    static void Main() {
        Action<string> logAction = Logger.Log; // Using Action delegate

        logAction("Application started!");
        logAction("User logged in.");
    }
}
				
			

πŸ“ Output:

				
					[LOG]: Application started!
[LOG]: User logged in.
				
			

πŸ”Ž Explanation:

βœ” Action<string> stores the Log() method.
βœ” The same delegate is reused for logging different messages.

Conclusion

Built-in Delegates in C# make coding simple and efficient.

➑️ Use Action<T> when no return value is needed.
➑️ Use Func<T, TResult> when a return value is needed.
➑️ Use Predicate<T> when returning bool.

Now go ahead and try them in your projects! Happy coding! πŸŽ‰

Β 

Next What?

Woohoo! πŸŽ‰ Now you know Built-in Delegates in C# like a pro! πŸš€

πŸ‘‰ Next, you will learn about OOPs – Properties and Indexers in C#! Stay excited! πŸš€

Leave a Comment

Share this Doc

Built-in Delegates

Or copy link