views:

635

answers:

6

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

Thanks!

+3  A: 

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
@Steven I would be interested in why you think that?
kenny
Favor composition over inheritance. -- http://www.artima.com/lejava/articles/designprinciples4.html
Robert Harvey
With a sealed class, you won't have any other option than using extension methods......
marc_s
Yes, a sealed class is a good example of a case where inheritance is impossible, so extension methods are worth considering.
Steven Sudit
@Robert Harvey: You couldn't have said it better. :)
Randolpho
@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
They don't. People are just too quick to jump on the inheritance bandwagon, is all.
Randolpho
When you say "Whenever possible, use inheritance", people react to it, is all.
Randolpho
+1 Nice answer Steven.
Robert Harvey
@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
+1  A: 

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!
ArsenMkrt
+5  A: 

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
or something like LINQ, which works across enumerable (or collection?) types?
Steve the Plant
@Steve Exactly, Skip and Take were implemented for LINQ as well.
Joseph
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
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...)
Steve the Plant
Good point. Extension methods were invented for Linq, so I would guess they solved a number of problems.
Robert Harvey
+9  A: 

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
+4  A: 

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
Ok, so what does this have to do with composition?
Steven Sudit
This has nothing to do with composition. See my comment to your reply.
Randolpho
+1  A: 

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
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
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
And that's a fine example of a case where inheritance isn't an option.
Steven Sudit
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