These questions are follow up to the question i a
Extension methods shine wherever functional programming is used.
Consider almost any Module-level functions you already have in your app and what they become when you tag them as extension methods. They become an opportunity for "active voice" over "passive voice". Active voice means the code reads as though an instance provides its own method for performing a particular task, rather than having the function perform an action passively on it.
ExtendUnlimitedCredit(AddVIP(tblCustomer, "Bill Gates"))
vs.
tblCustomer.AddVIP("Bill Gates").ExtendUnlimitedCredit()
Extension methods make this transformation simple. Eliminating nested function calls with "active voice" code is often an improvement. Plus, since our shop locks down its core classes, we were only able to utilize nested function calls prior to extension methods.
The other great things about extension methods:
They make your functions (because of Intellisense) more discoverable. And if you provided inline markup describing the purpose and use of your function, Intellisense will even provide a helpful tooltip describing the method and its use to the developer who discovers it (simply by pressing the dot). Functions not tagged as extension methods are not so readily discovered, may go unused and, as a result, someone else may invent their own flavor of said function.
Whereas you cannot actually implement a method for an interface, a extension method offers an alternate means that gives the appearance that you’ve done so.
Its beeing used to extend (add on) functionality of existing classes without actually changing them.
You can see this in how LINQ (System.Linq namespace and others) adds on a lot of functionality to all collections.
I use them to reuse my object model classes. I have a bunch of classes that represent objects that I have in a database. These classes are used in the client side only to display the objects so the basic usage is accessing properties.
public class Stock {
public Code { get; private set; }
public Name { get; private set; }
}
Because of that usage pattern I don't want to have business logic methods in these classes, so I make every business logic to be an extension method.
public static class StockExtender {
public static List <Quote> GetQuotesByDate(this Stock s, DateTime date)
{...}
}
This way I can use the same classes for business logic processing and for user interface displaying without overloading the client side with unnecessary code.
One interesting thing about this solution it's that my object model classes are dynamic generated using Mono.Cecil, so it would be very difficult to add business logic methods even if I wanted. I have a compiler that reads XML definition files and generate these stubs classes representing some object I have in the database. The only approach in this case is to extend them.
In addition to the other answers, extension methods are a great way of adding boiler-plate implementation to interfaces. For example, if you want all lists tto be sortable, add an extension method for IList<T>
.
You can (as already stated) also use extension methods to add methods to classes outside of your control; ever wanted a Reverse()
method on string
? Add one!
The only difference is that extension methods don't use virtual, and there is no null-check. You can use this to your advantage if you like:
public static void ThrowIfNull<T>(this T obj, string name) where T : class
{
if(obj == null) throw new ArgumentNullException(name);
}
Unlike regular utility methods, they make it very easy to write fluent interfaces; this is one of the reasons for their existance - i.e. with LINQ:
var foo = source.Where(predicate).OrderBy(selector);
is a lot more readable than:
var foo = Enumerable.OrderBy(Enumerable.Where(source,predicate),selector);
With regular methods, to use the first approach it would have to be regular instance methods, which would require changes (for example) to IEnumerable<T>
- not desirable.
I'm not aware of any performance implications. Using extension methods makes most sense when you don't have access to the source code and thus can't add the method to the class directly, and the method makes sense to be implemented as a function. This goes to the comment I made on your previous question, where one other person gave a sample for an extension method on the 'string' class that returned a bool based on whether the string was a valid email. This, IMO, is an example of when NOT to use an extension method, because that function isn't fundamental to the string type. Adding a Left(int) and a Right(int) function to 'string' does make sense, however.
Addressing your second question: my rule of thumb is that the extension method should be a "natural extension of functionality" on the type or that it should be a maintainable and readable part of a fluent interface.
An example of a "natural extension of functionality" is extending a data reader to return a default value if a DBNull is enountered. Not so natural would be extending data reader to return an instance of the entity represented by the data in multiple fields. In the latter case, you're injecting the wrong responsibilities into the poor object :).