51

Are there rules of thumb that help determine which to use in what case? Should I prefer one over the other most times?

Thanks!

Matt
  • 25,467
  • 18
  • 120
  • 187
djcouchycouch
  • 12,724
  • 13
  • 69
  • 108
  • 1
    I personally, at least recently, like extension methods. But this is true for me whenever I learn something new -- I use it constantly once I learn it :x :) – Zack Jul 15 '09 at 17:14

9 Answers9

38

Extension methods are useful, but they are harder to discover through the IDE than regular methods, since they are not attached to the original class and there are no clues as to where the code for them might reside. There are some best practice suggestions as to where to put them and how to name them, but these are only guidelines and there is no guarantee that someone will follow them.

Usually you would use extension methods if you are only adding functionality to a well known, well used class or interface such as the .Net base classes, that you don't have access to the code for. Extension methods also have the constraint in that you not only have to have the original assembly, you have to have the assembly with the extension methods in it, which must be understood by consumers of your code.

Using inheritance will allow you to add, remove or override functionality, and ensure that it is always present with the class when you build it.

womp
  • 115,835
  • 26
  • 236
  • 269
18

Extension methods should be used when you want to provide an implementation across a variety of types that should share the same behavior, but would otherwise be disimilar. That's why you see extension methods being used on interfaces a lot, because it's a very powerful tool to ensure that any given implementation of an interface will have the same implementation of a given behavior.

For example, the Skip and Take extension methods.

Joseph
  • 25,330
  • 8
  • 76
  • 125
  • or something like LINQ, which works across enumerable (or collection?) types? – djcouchycouch Jul 15 '09 at 16:01
  • 1
    @Steve Exactly, Skip and Take were implemented for LINQ as well. – Joseph Jul 15 '09 at 16:03
  • The Skip and Take extension methods are in the System.Linq.Queryable class, operate on the IQueryable interface, and return an IQueryable, which makes them chainable as well, i.e. Skip().Take() – Robert Harvey Jul 15 '09 at 16:12
  • So I guess if I were the designer of LINQ, I'd prefer extension methods because since LINQ calls will always imply an enumerable as the first parameter anyway, MyList.DoStuff(parameters...) would be preferable to LINQ.DoStuff(MyList, parameters...) – djcouchycouch Jul 15 '09 at 16:13
  • Good point. Extension methods were invented for Linq, so I would guess they solved a number of problems. – Robert Harvey Jul 15 '09 at 16:15
10

Well... you can't always use inheritance. String, for example, is a sealed class. It's in those cases where an extension method really shines.

In general, extension methods are best for little utilities that you might otherwise put into a static class, but that operate against an instance of a particular type. Strings are a great example -- almost everyone has their own little string extension methods to do little operations on a string.

Another great place for extension methods is against enumerations. I almost always include a HasFlag extension method against any [Flags] enumerations I create.

Randolpho
  • 55,384
  • 17
  • 145
  • 179
8

Whenever possible, use inheritance instead of extension methods.

edit

I prefer to keep this short and simple, but I will of course answer follow-up questions.

In the cases where inheritance is possible, which is to say classes that are not sealed, it is almost always a better option than extension methods. In fact, this is what the best practices document that womp referenced says. It has headings such as "Be wary of extension methods", "Think twice before extending types you don't own", and "Prefer interface extensions over class extensions". In other words, it just says what my one-liner did, with greater detail.

The article does give detailed reasons, but the bottom line is that this is how extension methods were designed to be used. They were added to the language late in the game as a bit of syntactic sugar to allow MS to wedge in LINQ without having to go back and reinvent the wheel. This is the canonical example of what they are good for. Another good example is adding utility methods, such as:

public static string FormatWith(this string format, params object[] args)
{ return string.Format(CultureInfo.InvariantCulture, format, args); }

Note that, in this case, extension methods were the only way to accomplish this additional feature, since strings are sealed.

As for composition over inheritance, while this is a truism, I fail to see the relevance here. Whether we're using extension methods or inheritance, the goal is to change the interface to allow another method. How this method is implemented, whether by composition, generics or some other technique, is orthogonal.

Steven Sudit
  • 19,391
  • 1
  • 51
  • 53
  • @Steven I would be interested in why you think that? – kenny Jul 15 '09 at 15:55
  • 7
    Favor composition over inheritance. -- http://www.artima.com/lejava/articles/designprinciples4.html – Robert Harvey Jul 15 '09 at 16:04
  • 1
    With a sealed class, you won't have any other option than using extension methods...... – marc_s Jul 15 '09 at 16:47
  • Yes, a sealed class is a good example of a case where inheritance is impossible, so extension methods are worth considering. – Steven Sudit Jul 15 '09 at 16:56
  • @Robert Harvey: You couldn't have said it better. :) – Randolpho Jul 15 '09 at 17:52
  • @Randolpho or @Robert Harvey: Could either of you please explain what extension methods have to do with composition? I just don't see the connection. – Steven Sudit Jul 15 '09 at 18:15
  • They don't. People are just too quick to jump on the inheritance bandwagon, is all. – Randolpho Jul 15 '09 at 19:56
  • 1
    When you say "Whenever possible, use inheritance", people react to it, is all. – Randolpho Jul 15 '09 at 19:57
  • @Randolpho: Thanks for pointing out that, if the context isn't considered, the original statement seemed to endorse inheritance over all alternatives, including composition, rather than just over extension methods. I've added a clarification, in italics. For a moment there, you had me wondering if there was a third type of composition that I hadn't considered! – Steven Sudit Jul 15 '09 at 23:07
2

They are very different, for example LINQ standard query operators are great example of extension methods that should be difficult to implement with inheritance, but if you have access to class and can change source it will be better to use inheritance,
EDIT
and here is some rules that I find here C# 3.0 Features: Extension Methods

  • Extension methods cannot be used to override existing methods
  • An extension method with the same name and signature as an instance method will not be called
  • The concept of extension methods cannot be applied to fields, properties or events
  • Use extension methods sparingly....overuse can be a bad thing!
Arsen Mkrtchyan
  • 49,896
  • 32
  • 148
  • 184
2

I would stick to inheritance except in the cases that extension methods were primarily designed for - extending sealed classes or creating scope-specific extensions. Also remember that they are static, so if these are methods and behaviours that you would need to override in other classes, you can't really use extensions.

Extension methods do have one really great feature that is an inherent benefit of their implementation. Since they are static methods, you can call them on a null object.

For instance:

string a = null;
return a.IfNullOrEmpty("Default Value");

Implementations like this are great, though they are technically just syntactical sugar. IMHO, anything that keeps your code cleaner and more readable is great.

Though I don't like that they aren't really discoverable. If I copy that code from one class to another, i would then have to search for the namespace in which it was defined.

Brian Rudolph
  • 6,142
  • 2
  • 23
  • 19
  • That's a good example. In fact, the first extension method I wrote was: public static bool IsNullOrEmpty(this string s) { return string.IsNullOrEmpty(s); } – Steven Sudit Jul 15 '09 at 17:20
  • Most of the extensions that I've written are designed to take advantage of null or empty objects\lists. I love that feature. – Brian Rudolph Jul 15 '09 at 17:23
  • And that's a fine example of a case where inheritance isn't an option. – Steven Sudit Jul 15 '09 at 17:31
  • And here's another, involving WinForm delegates: http://stackoverflow.com/questions/714666/is-it-appropriate-to-extend-control-to-provide-consistently-safe-invoke-begininvo – Steven Sudit Jul 15 '09 at 18:33
1

It really depends on the problem you need to solve, in most situations class inheritance and interfaces make naturally more sense than extension methods and thus should be preferred.

On the other hand, Extensions allow you to create useful methods applying not just to one class - which would otherwise be much more cumbersome to do with inheritance, if not almost impossible to achieve.

Last but not least, Extensions allow you to extend .NET Framework's builtin classes as well as 3rd party classes, even if you don't own or have no access to the sourcecode.

Here are some examples where extension methods are used for good reasons:


LinqPad uses extension methods, for example the .Dump() method with which you can dump (print) the contents of every kind of object to the output window.


The .NET framework itself uses extension methods in many places, for example in Linq:

public static TSource FirstOrDefault<TSource>(this 
                        System.Collections.Generic.IEnumerable<TSource> source)

which returns the first element or default of any enumerable collection of any object type.


An example, where extension methods are better than inheritance is the following: Say you want to create a method which is able to create a clone (copy) of any existing object. With Extensions (and generics, plus reflection) you can do it this way.

Matt
  • 25,467
  • 18
  • 120
  • 187
0

Extension methods break good OO design. To say they should be used on sealed classes that you do not have access to the code base is ridiculous. Classes that are sealed and you do not have access to are probably sealed for a reason (performance, thread safety) and to tag functionality blindly to these classes is down right dangerous. There is always a way of implementing the decorator pattern in a pure OO way and to not do it that way makes the code harder to read, maintain and refactor. As a rule of thumb, if a feature of a language smells bad then it should be avoided. I'm sure you could find one example where extension methods are useful however the truth is that the feature will be abused by those developers with minimal OO training.

ComeIn
  • 1,519
  • 17
  • 12
0

MSDN

In the page on extension methods in the C# programming guide it says:

General Guidelines

In general, we recommend that you implement extension methods sparingly and only when you have to. Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type. For more information, see Inheritance (C# Programming Guide).

When using an extension method to extend a type whose source code you cannot change, you run the risk that a change in the implementation of the type will cause your extension method to break.

MAQ
  • 95
  • 8