views:

2370

answers:

29

A "non-believer" of C# was asking me what the purpose to extension methods was. I explained that you could then add new methods to objects that were already defined, especially when you don't own/control the source to the original object.

He brought up "Why not just add a method to your own class?" We've been going round and round (in a good way). My general response is that it is another tool in the toolbelt, and his response is it is a useless waste of a tool... but I thought I'd get a more "enlightened" answer.

What are some scenarios that you've used extension methods that you couldn't have (or shouldn't have) used a method added on to your own class?

+1  A: 

I have only one word to tell about it: MAINTAINABILITY this is the key for extension methods use

Tamir
I think you might need more than one word because I don't understand what this means.
Outlaw Programmer
I would actually say that is an argument _against_ extention methods. One of the risks of extention methods is that they can be everywhere, created by everyone. Wildgrow can happen if not used carefully.
borisCallens
You can find all references easily, when you're using EM. Also, in order to change globally one method, you can do it from one place only
Tamir
+24  A: 

Don't forget tooling! When you add an extension method M on type Foo, you get 'M' in Foo's intellisense list (assuming the extension class is in-scope). This make 'M' much easier to find than MyClass.M(Foo,...).

At the end of the day, it's just syntactic sugar for elsewhere-static-methods, but like buying a house: 'location, location, location!' If it hangs on the type, people will find it!

Brian
There is also a slight negative to this: extension methods (such as those from System.Linq fill up IntelliSense autocomplete with a longer list, making it a little harder to navigate.
Jared Updike
+8  A: 

One of the great reasons for Extension methods is behind LINQ. Without extension methods a lot of what you can do in LINQ would be very hard. The Where(), Contains(), Select extension methods means a lot more functionality is added to existing types without changing their structure.

Ray Booysen
its not 'one of', its THE reason for extension methods.
gbjbaanb
How so? It is one of the many reasons for having extension methods, not the sole requirement. I can use extension methods without using LINQ.
Ray Booysen
+4  A: 

My personal argument for Extension methods is, they fit very well into an OOP design: consider the simple method

bool empty = String.IsNullOrEmpty (myString)

in comparison to

bool empty = myString.IsNullOrEmpty ();
Calamitous
I don't see what you example has to do with OOP. What do you mean?
Andrew Hare
it "seems" that the method belongs to the object
Calamitous
I think the one MAIN point about extension methods is NEVER EVER write an extension method that has code for null instances of the type that you are extending the method to. Bill Wagner has a great portion of his book on this topic here: http://tinyurl.com/76x24d
Ray Booysen
This is a bad example (can throw NullReferenceException) but he's on the right track. A better example might be replacing Math.abs(-4) with something like -4.abs();
Outlaw Programmer
to my knowledge (and to my experience, if memory serves), myString.IsNullOrEmpty() does not need to throw a NullReferenceException because extension methods do not require an object instance in order to fire.
David Alpert
As it may not be the optimal example, its 100% working, try testing: String x = null; Assert.AreEqual (true, x.IsNullOrEmpty ()); x = String.Empty; Assert.AreEqual (true, x.IsNullOrEmpty ());
Calamitous
Well color me surprised. I guess it is just syntactic sugar...
Outlaw Programmer
From an OOP perspective, it follows the Open/Close Principle. You can comfortably close your classes yet still extend it later, if necessary.
Ryan Riley
+1 I thought about trying this, assumed it wouldn't work. It works, and is incredibly useful.
Maslow
I'm personally not a fan of extension methods that are intended to work with a null instance -- it looks like one thing to the reader, but then does something else.
Mark Simpson
+46  A: 

The only advantage of extension methods is code readability. That's it.

Extension methods allow you to do this:

foo.bar();

instead of this:

Util.bar(foo);

Now there are a lot of things in C# that are like this. In other words there are many features in C# that seem trivial and don't have great benefit in and of themselves. However once you begin combining these features together you begin to see something just a bit bigger than the sum of its parts. LINQ benefits greatly from extension methods as LINQ queries would be almost unreadable without them. LINQ would be possible without extension methods, but not practical.

Extension methods are a lot like C#'s partial classes. By themselves they are not very helpful and seem trivial. But when you start working with a class that needs generated code, partial classes start to make a lot more sense.

Andrew Hare
This becomes even more important if you are using chained methods like x.Foo(something).Bar(somethingelse).Baz(yetmoresomething).This is most prevalant in the IEnumerable<> extension methods and significantly increase readability
ShuggyCoUk
The thing I don't get is that foo.bar() suggests to me that bar() is a method of foo. So when it doesn't work I end up looking in the wrong place. I'm not sure this is actually a readability improvement for me.
Martin Brown
Right clicking bar() in VS IDE and chosing to Goto the Definition would bring you to the right place.
Jeff Martin
The only advantage of 98% of language constructs are code readability. Anything past a branch operator, label, goto and increment is there to make your life a little easier.
Giovanni Galbo
That's not entirely true, there is some situations that extension methods are the *only* way to extend a class. Besides sealed classes I use them in a pretty unique situation. See my post below.
Augusto Radtke
+8  A: 

Fluent Interfaces and Context Sensitivity as demonstrated by Greg Young on CodeBetter

cgreeno
A: 

It allows C# to better support dynamic languages, LINQ and a dozen other things. Check out Scott Guthrie's article.

DavGarcia
+15  A: 

I think extension methods help a lot when writing code, if you add extension methods to basic types you'll get them quicky in the intellisense.

I have a format provider to format a file size. To use it I need to write:

Console.WriteLine(String.Format(new FileSizeFormatProvider(), "{0:fs}", fileSize));

Creating an extension method I can write:

Console.WriteLine(fileSize.ToFileSize());

Cleaner and simpler.

Eduardo Campañó
a more descriptive name for your extension method would make it cleaner still. e.g. fileSize.ToFormattedString();
David Alpert
mmm, ToFormattedFizeSize() maybe, it's an extension method for a Long type, ToFormattedString() is not a descriptive name
Eduardo Campañó
point made, though. when i read fileSize.ToFileSize() i ask why the duplication? what's it actually doing? i know that it's only an example, but descriptive names help make it clean and simple.
David Alpert
you're right as with tests it's very important to choose the right name
Eduardo Campañó
That was the example I was going to post. My most used extension method is adding String.Format like syntax to Trace.WriteLine()
L2Type
I'm glad we can all agree on the name to use and the semantics it should have, would hate to end up with 15 extension methods that do nearly the same thing.
Roger Pate
This isn't really answering the question directly, though, since the example you provided doesn't need to be an extension method. You could have had `LongToFileSize(fileSize)`, which is just as concise and arguably just as clear.
Dan Tao
@Dan: +2 if I could
peterchen
You're right Dan, the generated IL is the same, it's a tool, you can use it or not. I find it really useful, particulary extending sealed classes or just not inherit. Advantages, like others said, code readability (cleaner and simpler), tooling, fluent...
Eduardo Campañó
+3  A: 

Its true that you can add your (extension) method directly into your class. But not all classes are written by you. Classes from the core library or third party libraries are often closed and it would be impossible to get the syntatic sugar without extension methods. But remember, extension methods are just like (static) standalone methods in eg. c++

Schildmeijer
+1  A: 

Extension methods are really the .NET incorporation of the "Introduce Foreign Method"refactor from Martin Fowler's Book (down to the method signature). They come with basically the same benefits and pitfalls. In the section on this refactor he says that they're a work-around for when you can't modify the class that should really own the method.

Jason Punyon
+1, but note that you can use extension methods with interfaces as well.
TrueWill
+8  A: 

This topic has been explored by the guys over at Microsoft: http://blogs.msdn.com/mirceat/archive/2008/03/13/linq-framework-design-guidelines.aspx

The executive summary: don't use them just because you can.

Matt Brunell
+18  A: 

Two more benefits of extension methods that i have come across:

  • a fluent interface can be encapsulated in a static class of extension methods, thereby achieving a separation of concerns between the core class and it's fluent extensions; i've seen that achieve greater maintainability
  • extension methods can be hung off of interfaces, thereby allowing you to specify a contract (via an interface) and an associated series of interface-based behaviors (via extension methods), again offering a separation of concerns.
David Alpert
A: 

Bill Wagner has some good examples of how you can use extension methods to make you code more readable and maintainable.

Here are the slides from the presentation he does on it. ExtensionMethods.pdf

epotter
+1  A: 

In my last project, I used extension method to attach Validate() methods to business objects. I justified this because the business objects where serializable data transfer objects and will be used in diffrent domains as they where general ecommerce entities such as product, customer, merchant etc. Well in diffrent domains the business rules may be diffrent as well so I encapsulated my late bound validation logic in a Validate method attahced to the base class of my data transfer objects. Hope this makes sense :)

A: 

I mainly see extension methods as an admission that perhaps they shouldn't have disallowed free functions.

In the C++ community, it is often considered good OOP practice to prefer free nonmember functions over members, because these functions don't break encapsulation by gaining access to private members they don't need. Extension methods seem to be a roundabout way to achieve the same thing. That is, a cleaner syntax for static functions which don't have access to private members.

Extension methods are nothing more than syntactic sugar, but I don't see any harm in using them.

jalf
+15  A: 

Some of the best uses I had for extension methods is the ability to:

  1. Extend functionality on third party objects (whether commercial or internal to my company but managed by a separate group), which in many cases will be marked as sealed.
  2. Create default functionality for interfaces without having to implement an abstract class

Take for example, IEnumerable<T>. While it is rich in extension methods, I found it annoying that it did not implement a generic ForEach method. So, I made my own:

public void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
    foreach ( var o in enumerable )
    {
        action(o);
    }
}

Voila, all my IEnumerable<T> objects regardless of implementing type, and whether or not I wrote it or someone else did now have a ForEach method by adding an appropriate "using" statement in my code.

Jon Limjap
+1 I love this extension, I wrote one just like it. So very useful
Maslow
Note that the method needs to be static. I suggest reading http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx before deciding to use this extension.
TrueWill
A: 

I think extension methods help to write code that is clearer.

Instead of putting a new method inside your class, as your friend suggested, you put it in the ExtensionMethods namespace. In this way you maintain a logical sense of order to your class. Methods that don't really directly deal with your class won't be cluttering it up.

I feel extension methods make your code clearer and more appropriately organized.

Alex Baranosky
+2  A: 

Extension methods can also help keep your classes and class dependencies clean. For instance, you may need a Bar() method for the Foo class everywhere Foo is used. However, you may want a .ToXml() method in another assembly and only for that assembly. In that case, you can add the necessary System.Xml and/or System.Xml.Linq dependencies in that assembly and not in the original assembly.

Benefits: dependencies in your defining class assembly is reduced to only the bare necessities and other consuming assemblies will be prevented from using the ToXml() method. See this PDC presentation for further reference.

Ryan Riley
+1  A: 

One case where extension methods were quite useful was in a client-application that uses ASMX web services. Due to the serialization, the return types of web methods do not contain any methods (only the public properties of these types are available on the client).

Extension methods allowed use to add functionality (on the client-side) to the types returned by web methods without having to create yet another object model or numerous wrapper classes on the client-side.

M4N
+1  A: 
  • Intellisense on the object itself instead of having to call some ugly utility function
  • For conversion functions, can change "XToY(X x)" to "ToY(this X x)" which results in pretty x.ToY() instead of ugly XToY(x).
  • Extend classes you have no control over
  • Extend functionality of classes when its undesirable to add methods to the classes themselves. For example, you can keep business objects simple and logic-free, and add specific business logic with ugly dependencies in extension methods
davogones
+1  A: 

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.

Augusto Radtke
You could use partial classes for this...
JJoos
+1  A: 

There are heaps of great answers above about what extension methods let you do.

My short answer is - they nearly eliminate the need for factories.

I'll just point out that they are not a new concept and one of the biggest validations of them is that they are a killer feature in Objective-C (categories). They add so much flexibility to framework-based development that NeXT had NSA and Wall Street financial modelers as major users.

REALbasic also implements them as extends methods and they have been of similar use there simplifying development.

Andy Dent
A: 

It allows your editor/IDE do auto-complete suggestion smart.

Dennis Cheung
A: 

I love them for building html. Frequently there are sections that are used repeatedly, or generated recursively where a function is useful but would otherwise break the flow of the program.

        HTML_Out.Append("<ul>");
        foreach (var i in items)
            if (i.Description != "")
            {
                HTML_Out.Append("<li>")
                    .AppendAnchor(new string[]{ urlRoot, i.Description_Norm }, i.Description)
                    .Append("<div>")
                    .AppendImage(iconDir, i.Icon, i.Description)
                    .Append(i.Categories.ToHTML(i.Description_Norm, urlRoot)).Append("</div></li>");
            }

        return HTML_Out.Append("</ul>").ToString();

There are also situations where an object needs custom logic to be prepared for HTML output- extension methods let you add this functionality without mixing presentation and logic within the class.

apocalypse9
A: 

I've found extension methods are useful to match nested generic arguments.

That sounds a bit wierd - but say we have a generic class MyGenericClass<TList>, and we know that TList itself is generic (e.g. a List<T>), I don't think that there's a way to dig out that nested 'T' from the List without either extension methods or static helper methods. If we only have static helper methods at our disposal, it's (a) ugly, and (b) will force us to move functionality that belongs in the class to an external location.

e.g. to retrieve the types in a tuple and convert them into a method signature we can use extension methods:

public class Tuple { }
public class Tuple<T0> : Tuple { }
public class Tuple<T0, T1> : Tuple<T0> { }

public class Caller<TTuple> where TTuple : Tuple { /* ... */ }

public static class CallerExtensions
{
     public static void Call<T0>(this Caller<Tuple<T0>> caller, T0 p0) { /* ... */ }

     public static void Call<T0, T1>(this Caller<Tuple<T0, T1>> caller, T0 p0, T1 p1) { /* ... */ }
}

new Caller<Tuple<int>>().Call(10);
new Caller<Tuple<string, int>>().Call("Hello", 10);

That said, I'm not sure where the dividing line should be - when should a method be an extension method, and when should it be a static helper method? Any thoughts?

Andy
A: 

There are plenty of answers about the advantages of extensions methods; how about one addressing the disadvantages?

The biggest disadvantage is that there's no compiler error or warning if you have a regular method and an extension method with the same signature in the same context.

Suppose you create an extension method applying to a particular class. Then later someone creates a method with an identical signature on that class itself.

Your code will compile, and you may not even get a runtime error. But you're no longer running the same code as before.

Kyralessa
A: 

I agree that extension methods increases readability of code, but it's really nothing else than static helper methods.

IMO using extension methods for adding behaviour to your classes can be:

Confusing: Programmers might believe that methods are a part of the extended type, thus not understanding why the methods are gone when the extension-namespace isn't imported.

An antipattern: You decide to add behaviour to types in your framework using extension methods, then shipping them off to some person which into unit testing. Now he's stuck with a framework containing a bunch of methods he can't fake.

HaraldV
A: 

Extension methods can be used to create a kind of mixin in C#.

This, in turn, provides better separation of concerns for orthogonal concepts. Take a look at this answer as an example.

This can also be used to enable roles in C#, a concept central to the DCI architecture.

Jordão
+1  A: 

I would like to support the other answers here that mention improved code readability as an important reason behind extension methods. I'll demonstrate this with two aspects of this: method chaining vs. nested method calls, and cluttering of a LINQ query with meaningless static class names.


Let's take this LINQ query as an example:

numbers.Where(x => x > 0).Select(x => -x)

Both Where and Select are extension methods, defined in the static class Enumerable. Thus, if extension methods didn't exist, and these were normal static methods, the last line of code would essentially have to look like this:

Enumerable.Select(Enumerable.Where(numbers, x => x > 0), x => -x)

See how much nastier that query just got.


Second, if you now wanted to introduce your own query operator, you would naturally have no way of defining it inside the Enumerable static class, like all the other standard query operators, because Enumerable is in the framework and you have no control over that class. Therefore, you'd have to define your own static class containing extension methods. You might then get queries such as this one:

Enumerable.Select(MyEnumerableExtensions.RemoveNegativeNumbers(numbers), x => -x)
//                ^^^^^^^^^^^^^^^^^^^^^^
//                different class name that has zero informational value
//                and, as with 'Enumerable.xxxxxx', only obstructs the
//                query's actual meaning.
stakx