DEV Community

mohamed Tayel
mohamed Tayel

Posted on

C# Advanced:Extension Methods Demo

In C#, you may sometimes need to extend the functionality of existing classes or interfaces that you don't own. One powerful feature that allows you to do this is Extension Methods. They let you "add" methods to types like IEnumerable<T> without modifying the actual code of those types.

In this article, we’ll explore how to create a useful extension method for IEnumerable<T> and walk through an example that demonstrates its power and flexibility.


What are Extension Methods?

Extension methods enable you to add new methods to existing types without changing their original source code. Instead of modifying the class, you define these methods in a static class.

The most common scenario where extension methods shine is when working with built-in interfaces or classes, such as IEnumerable<T>. You might want to add custom methods to these types to suit your specific needs.

Let’s say you want to search for specific items in a collection (like a list). Since you can't modify IEnumerable<T>, you can extend it by creating an extension method!


A Simple Example: Adding a Find Method to IEnumerable<T>

Let’s imagine we want to add a method called Find to IEnumerable<T> that searches for items in a collection based on a condition. Here's how we can create this method using extension methods.

using System;
using System.Collections.Generic;

namespace ExtensionMethodExample
{
    // Step 1: Create a static class to hold the extension methods
    public static class IEnumerableExtensions
    {
        // Step 2: Define a static extension method called 'Find'
        public static IEnumerable<T> Find<T>(this IEnumerable<T> source, Func<T, bool> predicate)
        {
            // Step 3: Iterate through the collection and find matching items
            foreach (var item in source)
            {
                if (predicate(item))
                {
                    // Step 4: Use 'yield return' to return matching items one by one
                    yield return item;
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Example: Using the 'Find' extension method to search a list of numbers

            List<int> numbers = new List<int> { 1, 5, 10, 20, 25, 30 };

            // Find all numbers greater than 10
            var results = numbers.Find(n => n > 10);

            // Print the results
            Console.WriteLine("Numbers greater than 10:");
            foreach (var number in results)
            {
                Console.WriteLine(number);
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Breakdown

  1. Create a Static Class

    To define extension methods, you need to place them in a static class. In this case, we create a class called IEnumerableExtensions.

  2. Define the Extension Method

    The extension method Find<T> takes two parameters:

    • this IEnumerable<T> source: This tells the compiler that this method is an extension for any IEnumerable<T>.
    • Func<T, bool> predicate: This is a delegate (think of it as a condition) that tells the method how to search for the items.
  3. Using the foreach Loop and yield Keyword

    We loop through each item in the collection. If the condition (predicate) is met, we return the item using the yield return keyword. Using yield allows items to be returned one by one, instead of creating a large list first.

  4. Using the Extension Method

    In the Main method, we create a list of integers and use our new Find method to search for numbers greater than 10. We pass a lambda expression (n => n > 10) as the search condition.


Why Use Extension Methods?

Extension methods are extremely useful when you want to:

  • Add reusable functionality to types you don't own or can't modify.
  • Improve code readability by making the method feel like it belongs to the type.
  • Maintain a clean and organized codebase without having to write static utility classes all the time.

Real-World Example: Searching Products

Let’s take a more realistic example. Imagine you have a list of products, and you want to search for products that are priced above a certain threshold. Here's how you can do that with extension methods:

using System;
using System.Collections.Generic;

namespace ExtensionMethodExample
{
    public class Product
    {
        public string Name { get; set; }
        public decimal Price { get; set; }
    }

    public static class IEnumerableExtensions
    {
        public static IEnumerable<T> Find<T>(this IEnumerable<T> source, Func<T, bool> predicate)
        {
            foreach (var item in source)
            {
                if (predicate(item))
                {
                    yield return item;
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Product> products = new List<Product>
            {
                new Product { Name = "Laptop", Price = 1000m },
                new Product { Name = "Phone", Price = 500m },
                new Product { Name = "Tablet", Price = 300m }
            };

            // Find all products priced above $400
            var expensiveProducts = products.Find(p => p.Price > 400m);

            Console.WriteLine("Products priced above $400:");
            foreach (var product in expensiveProducts)
            {
                Console.WriteLine($"{product.Name}: ${product.Price}");
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

Products priced above $400:
Laptop: $1000
Phone: $500
Enter fullscreen mode Exit fullscreen mode

In this example:

  • We define a list of Product objects.
  • We use our Find extension method to search for products priced above $400.
  • The results are displayed, and only the matching products are shown.

Conclusion

Extension methods in C# offer a flexible and powerful way to extend the functionality of existing types, like IEnumerable<T>. Whether you're searching through lists, arrays, or more complex collections, you can use extension methods to create reusable, clean code.

In our example, we added a Find method to search through collections using a delegate and lambda expressions. This is just one of many ways you can leverage extension methods in your daily coding tasks. The next time you need to add functionality to a type you don’t own, consider using extension methods!


Assignment

To reinforce what you’ve learned, try writing an extension method that:

  1. Searches for the highest-priced product in a list.
  2. Filters out all products under a certain price.

Happy coding!

Top comments (0)