C# tutorials > Core C# Fundamentals > Object-Oriented Programming (OOP) > What are extension methods?
What are extension methods?
Extension methods enable you to add new methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. They are a special kind of static method that is called as if they were instance methods on the extended type. This allows you to 'inject' functionality into classes or interfaces you don't own, making your code more readable and maintainable. They are defined in a static class, and the first parameter specifies the type that the method operates on, preceded by the this
keyword.
Basic Syntax and Example
This code defines an extension method called Capitalize
for the string
type. Notice that the method is defined within a static
class called StringExtensions
and is also a static
method. The first parameter of the Capitalize
method is this string str
. The this
keyword specifies that this is an extension method and that it extends the string
type. The method takes a string as input and returns a new string with the first letter capitalized. The Main
method demonstrates how to use the extension method. You call Capitalize
as if it were an instance method of the string
class.
using System;
public static class StringExtensions
{
public static string Capitalize(this string str)
{
if (string.IsNullOrEmpty(str))
{
return str;
}
return char.ToUpper(str[0]) + str.Substring(1);
}
}
public class Example
{
public static void Main(string[] args)
{
string myString = "hello world";
string capitalizedString = myString.Capitalize();
Console.WriteLine(capitalizedString); // Output: Hello world
}
}
Concepts Behind the Snippet
The core concept behind extension methods is to provide a way to extend the functionality of existing types without modifying them directly. This adheres to the Open/Closed Principle from the SOLID principles, which states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. Extension methods are resolved at compile time. The compiler searches for extension methods in scope based on namespaces that are imported with using
directives. The correct extension method is selected based on the type of the object and the name and parameters of the method call.
Real-Life Use Case Section
A common real-life use case is adding pagination to IEnumerable
collections. The code above defines an extension method called Page
that takes an IEnumerable
, a page number, and a page size as input, and returns a new IEnumerable
containing only the items for the specified page. This functionality is useful when displaying large datasets in a user interface, where it's often necessary to break the data into smaller, more manageable pages.
using System;
using System.Collections.Generic;
using System.Linq;
public static class EnumerableExtensions
{
public static IEnumerable<T> Page<T>(this IEnumerable<T> source, int page, int pageSize)
{
if (pageSize <= 0)
{
throw new ArgumentOutOfRangeException("pageSize", "Page size must be greater than zero.");
}
if (page <= 0)
{
throw new ArgumentOutOfRangeException("page", "Page number must be greater than zero.");
}
return source.Skip((page - 1) * pageSize).Take(pageSize);
}
}
public class Example
{
public static void Main(string[] args)
{
List<int> numbers = Enumerable.Range(1, 50).ToList();
// Get the first page of 10 items
IEnumerable<int> firstPage = numbers.Page(1, 10);
foreach (int number in firstPage)
{
Console.WriteLine(number);
}
//Output 1 to 10
}
}
Best Practices
StringExtensions
.
Interview Tip
When discussing extension methods in an interview, be prepared to explain their purpose, syntax, and benefits. Also, be ready to discuss scenarios where extension methods are appropriate and where they are not. Demonstrate your understanding of the Open/Closed Principle and how extension methods help to adhere to it. A good interview answer will also cover performance considerations and potential drawbacks, such as the possibility of naming conflicts.
When to Use Them
Use extension methods when you want to add functionality to a type that you don't own or cannot modify. This is especially useful when working with third-party libraries or framework types. Extension methods are also a good way to add utility methods to your own types without cluttering the original class definition.
Memory Footprint
Extension methods themselves don't introduce a significant memory footprint. They are static methods, and their code resides in the method table of the static class where they are defined. The impact on memory comes from the data structures that are created and used within the extension method itself. For example, the Capitalize
method creates a new string object, which consumes memory. The Page
extension method creates an iterator which can have a small footprint.
Alternatives
Pros
Cons
FAQ
-
Can I create extension methods for interfaces?
Yes, you can create extension methods for interfaces. This allows you to provide default implementations for interface methods, which can be useful when adding new methods to an existing interface without breaking existing implementations.
-
Can I extend sealed classes using extension methods?
Yes, extension methods are a great way to add functionality to sealed classes because you cannot inherit from them.
-
What happens if an extension method has the same signature as an existing method of the type?
If an extension method has the same signature as an existing method (instance method) of the type, the instance method will always take precedence. The extension method will only be called if there is no matching instance method.