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);
}
}
}
}
Step-by-Step Breakdown
Create a Static Class
To define extension methods, you need to place them in a static class. In this case, we create a class calledIEnumerableExtensions
.-
Define the Extension Method
The extension methodFind<T>
takes two parameters:-
this IEnumerable<T> source
: This tells the compiler that this method is an extension for anyIEnumerable<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.
-
Using the
foreach
Loop andyield
Keyword
We loop through each item in the collection. If the condition (predicate
) is met, we return the item using theyield return
keyword. Usingyield
allows items to be returned one by one, instead of creating a large list first.Using the Extension Method
In theMain
method, we create a list of integers and use our newFind
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}");
}
}
}
}
Output:
Products priced above $400:
Laptop: $1000
Phone: $500
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:
- Searches for the highest-priced product in a list.
- Filters out all products under a certain price.
Happy coding!
Top comments (0)