views:

161

answers:

6

Possible Duplicate:
What Advantages of Extension Methods have you found?

All right, first of all, I realize this sounds controversial, but I don't mean to be confrontational. I am asking a serious question out of genuine curiosity (or maybe puzzlement is a better word).

Why were extension methods ever introduced to .NET? What benefit do they provide, aside from making things look nice (and by "nice" I mean "deceptively like instance methods")?

To me, any code that uses an extension method like this:

Thing initial = GetThing();
Thing manipulated = initial.SomeExtensionMethod();

is misleading, because it implies that SomeExtensionMethod is an instance member of Thing, which misleads developers into believing (at least as a gut feeling... you may deny it but I've definitely observed this) that (1) SomeExtensionMethod is probably implemented efficiently, and (2) since SomeExtensionMethod actually looks like it's part of the Thing class, surely it will remain valid if Thing is revised at some point in the future (as long as the author of Thing knows what he/she's doing).

But the fact is that extension methods don't have access to protected members or any of the internal workings of the class they're extending, so they're just as prone to breakage as any other static methods.

We all know that the above could easily be:

Thing initial = GetThing();
Thing manipulated = SomeNonExtensionMethod(initial);

To me, this seems a lot more, for lack of a better word, honest.

What am I missing? Why do extension methods exist?

A: 

SO you can extend someone else's class. not yours... that's the advantage. (and you can say.. oh I wish they implement this / that.... you just do it yourself..)

Dani
Hell - @Zarembisty is so right - go to that like he posted. you get everyting there ! stackoverflow.com/questions/487904/… – Zarembisty.
Dani
My point is that they don't give you any more power than simply using static methods does.
Dan Tao
+10  A: 

Extension methods were needed to make Linq work in the clean way that it does, with method chaining. If you have to use the "long" form, it causes the function calls and the parameters to become separated from each other, making the code very hard to read. Compare:

IEnumerable<int> r = list.Where(x => x > 10).Take(5)

versus

// What does the 5 do here?
IEnumerable<int> r = Enumerable.Take(Enumerable.Where(list, x => x > 10), 5);

Like anything, they can be abused, but extension methods are really useful when used properly.

Mark Byers
I know this question is closed, but this was my favorite answer.
Dan Tao
+6  A: 

I think that the main upside is discoverability. Type initial and a dot, and there you have all the stuff that you can do with it. It's a lot harder to find static methods tucked away in some class somewhere else.

Fredrik Mörk
Isn't this really more a consequence of Visual Studio's functionality, though, rather than an inherent benefit of extension methods as part of C#/.NET?
Dan Tao
@Dan: yes, if you use another editor that does not discover the extension methods and show them as Intellisense does, that benefit is gone.
Fredrik Mörk
+3  A: 

First of all, in the Thing manipulated = SomeNonExtensionMethod(initial); case, SomeNonExtensionMethod is based on exactly the same assumptions like in the Thing manipulated = initial.SomeExtensionMethod(); case. Thing can change, SomeExtensionMethod can break. That's life for us programmers.

Second, when I see Thing manipulated = initial.SomeExtensionMethod();, it doesn't tell me exactly where SomeExtensionMethod() is implemented. Thing could inherit it from TheThing, which inherits it from TheOriginalThing. So the "misleading" argument leads to nowhere. I bet the IDE takes care of leading you to the right source, doesn't it?

What's so great? It makes code more consistent. If it works on a string, it looks like if it was a member of string. It's ugly to have several MyThing.doThis() methods and several static ThingUtil.doSomethingElse(Mything thing) methods in another class.

ammoQ
To your first point: my point is that the two are in fact the same, but the `SomeNonExtensionMethod` version is less misleading because it doesn't trick you into thinking the method is actually part of the class definition.
Dan Tao
To your second point: at least if you call an instance member, you know it is implemented internally by the class, which means at the very least it has access to protected members and *should* be guaranteed to continue to work whenever the class is updated.
Dan Tao
To your last point: to say it's "ugly" to have static methods do work on an object strikes me as very subjective. I'm having trouble seeing the benefit. I might wish the C# design team would allow replacing curly braces with square brackets because that looks prettier to me; that doesn't mean for them to do that would improve the language.
Dan Tao
Dan: First: I don't think it matters a lot whether or not it is part of the class definition or not. Either it works as expected, or it doesn't.
ammoQ
Dan: Second: As an outsider, I don't know anything about protected members. I don't care how SomeExtensionMethod() does what it does. Too much knowledge about that leads to assumptions, possibily to hidden dependencies. WOrk whenever the class is updated: I guess you use extension methods for classes that are very stable, like string. You wouldn't use that for your own classes, since you can always change _them_ instead.
ammoQ
Dan: Third: ThingUtil.staticDoSomething(Thing it) is ugly because this is the functional decomposition antipattern. Technically, the extension methods are not better, but at least it's less visible.
ammoQ
A: 

they are great for automatically mixing in functionality based on Interfaces that a class inherits without that class having to explicitly re implement it.

Linq makes use of this a lot.

Great way to decorate classes with extra functionality. Most effective when applied to an Interface rather than a specific class. Still a good way to extend Framework classes though.

Keith Nicholas
A: 

It's just convenient syntactic sugar so that you can call a method with the same syntax regardless of whether it's actually part of the class. If party A releases a lib, and party B releases stuff that uses that lib, it's easier to just call everything with class.method(args) than to have to remember what gets called with method(class, args) vs. class.method(args).

dsimcha