DEV Community

mohamed Tayel
mohamed Tayel

Posted on

C# Advanced:Understanding `Action` and `Func`

Meta Description :Learn how to simplify your C# code with Action and Func delegates. This beginner-friendly guide includes detailed explanations, step-by-step examples, and assignments to help you apply what you’ve learned, ranging from easy to difficult levels

In C#, Action and Func are two important generic delegates that simplify code by allowing methods to be passed as parameters and assigned to variables. However, understanding how to use these delegates effectively can be tricky for beginners. This article provides a simplified explanation and four detailed examples for both Action and Func, each broken down step-by-step, followed by assignments at three levels: easy, medium, and difficult.


What is Action?

An Action delegate represents a method that can take up to 16 parameters and does not return a value (it always returns void). You use Action when you want to perform an operation but don't need any output from the method.


Action Examples

1. Easy Example: Printing a Simple Message

Action sayHello = () => Console.WriteLine("Hello, World!");
sayHello();  // Output: Hello, World!
Enter fullscreen mode Exit fullscreen mode

Breakdown:

  • What is happening? Action is declared with no parameters, and the lambda expression () => Console.WriteLine("Hello, World!") defines the method that the Action points to.
  • What does it do? When sayHello() is called, it prints "Hello, World!" to the console.
  • Why is this useful? This is a simple way to encapsulate and reuse a method that performs a specific action without needing to pass any data or return a value.

2. Medium Example: Reversing a String

Action<string> reversePrint = (input) => {
    char[] charArray = input.ToCharArray();
    Array.Reverse(charArray);
    Console.WriteLine(new string(charArray));
};
reversePrint("CSharp");  // Output: prahSC
Enter fullscreen mode Exit fullscreen mode

Breakdown:

  • What is happening? This Action takes one parameter: a string (input). The string is converted into a character array, reversed, and then printed as a new string.
  • What does it do? It takes any input string, reverses the characters, and prints the result. In this case, "CSharp" becomes "prahSC".
  • Why is this useful? It’s a quick way to define an action that modifies and prints a string without creating a separate method.

3. Hard Example: Calculating the Sum of Two Numbers

Action<int, int> printSum = (a, b) => Console.WriteLine($"Sum: {a + b}");
printSum(5, 7);  // Output: Sum: 12
Enter fullscreen mode Exit fullscreen mode

Breakdown:

  • What is happening? This Action takes two integer parameters (a and b). It calculates the sum of these two numbers and prints the result.
  • What does it do? The sum of a and b is computed and printed. In this case, 5 + 7 = 12.
  • Why is this useful? It's a clean way to perform and display the sum of two numbers without needing to write a full method.

4. Difficult Example: Printing the Squares of an Array of Numbers

Action<int[]> printSquares = (numbers) => {
    foreach (var num in numbers)
    {
        Console.WriteLine($"Square of {num}: {num * num}");
    }
};
printSquares(new int[] { 1, 2, 3, 4, 5 });  
// Output:
// Square of 1: 1
// Square of 2: 4
// Square of 3: 9
// Square of 4: 16
// Square of 5: 25
Enter fullscreen mode Exit fullscreen mode

Breakdown:

  • What is happening? This Action takes an array of integers as input. For each integer, it calculates the square (num * num) and prints the result.
  • What does it do? For each number in the array, it calculates the square and prints it. For example, 2 squared is 4, 3 squared is 9, and so on.
  • Why is this useful? This demonstrates how Action can work with arrays and perform operations on each element.

What is Func?

Func is similar to Action, but it returns a value. The last generic parameter of Func defines the return type. You use Func when you want to pass a method that both takes parameters and returns a result.


Func Examples

1. Easy Example: Returning the Length of a String

Func<string, int> getLength = (str) => str.Length;
int length = getLength("CSharp");  // length = 6
Console.WriteLine(length);  // Output: 6
Enter fullscreen mode Exit fullscreen mode

Breakdown:

  • What is happening? This Func takes a string as input and returns an integer representing its length.
  • What does it do? For the input "CSharp", it returns the number of characters, which is 6.
  • Why is this useful? It’s a quick and reusable way to calculate the length of any string.

2. Medium Example: Checking If a Number Is Even

Func<int, bool> isEven = (num) => num % 2 == 0;
bool result = isEven(10);  // result = true
Console.WriteLine(result);  // Output: True
Enter fullscreen mode Exit fullscreen mode

Breakdown:

  • What is happening? This Func takes an integer as input and returns a boolean (true or false), indicating whether the number is even.
  • What does it do? It checks if the number is divisible by 2. For 10, the result is true.
  • Why is this useful? It simplifies checking for even numbers and can be used wherever such logic is needed.

3. Hard Example: Calculating the Maximum of Two Numbers

Func<int, int, int> getMax = (a, b) => (a > b) ? a : b;
int max = getMax(10, 15);  // max = 15
Console.WriteLine(max);  // Output: 15
Enter fullscreen mode Exit fullscreen mode

Breakdown:

  • What is happening? This Func takes two integers as input and returns the larger of the two.
  • What does it do? It compares a and b, returning whichever is larger. In this case, 15 is greater than 10.
  • Why is this useful? It provides an easy way to find the maximum of two numbers without writing a separate method.

4. Difficult Example: Returning a New String Based on a Condition

Func<string, string, string> compareStrings = (str1, str2) => {
    return str1.Equals(str2) ? "Strings are equal" : "Strings are different";
};
string result = compareStrings("hello", "world");  // result = Strings are different
Console.WriteLine(result);  // Output: Strings are different
Enter fullscreen mode Exit fullscreen mode

Breakdown:

  • What is happening? This Func takes two string parameters and returns a new string indicating whether the two input strings are equal or different.
  • What does it do? It compares the two strings and returns "Strings are equal" if they match, or "Strings are different" if they do not.
  • Why is this useful? It simplifies string comparison and can be reused wherever this logic is needed.

Assignments

Now that you’ve seen several examples of Action and Func, it’s time to practice what you’ve learned. Here are three assignments at different levels to help you apply the concepts.

Easy Assignment

Create an Action that takes a string and prints the string in uppercase letters.

Action<string> printUpper = // Your code here
printUpper("hello");  // Output: HELLO
Enter fullscreen mode Exit fullscreen mode

Medium Assignment

Write a Func that takes two integers and returns their greatest common divisor (GCD). The GCD is the largest number that divides both numbers evenly.

Func<int, int, int> gcd = // Your code here
int result = gcd(54, 24);  // Output: 6 (since 6 is the GCD of 54 and 24)
Console.WriteLine(result);
Enter fullscreen mode Exit fullscreen mode

Difficult Assignment

Create a program where you:

  1. Use a Func<int, bool> to determine if a number is prime.
  2. Use an Action<int[]> to print all prime numbers between 1 and 100 using the Func from step 1.
Func<int, bool> isPrime = // Your code here
Action<int[]> printPrimes = // Your code here

int[] numbers = Enumerable.Range(1, 100).ToArray();
printPrimes(numbers);  // Output: 2, 3, 5, 7, 11, ..., 97
Enter fullscreen mode Exit fullscreen mode

Conclusion

By using Action and Func, you can make your code more flexible, concise, and reusable. Each of these examples demonstrates how you can apply these delegates for

different tasks, ranging from simple actions to more complex logic. Try working through these examples and assignments to strengthen your understanding!

Top comments (0)