14

I have a piece of code like the following:

public class ActivityHelper
{
    public void SetDate(IList<Activity> anActivityList)
    {
        foreach(Activity current in anActivityList)
        {
            current.Date = DateTime.Now;
        }
    }
    //More methods, properties, fields, etc...
}

This could easily be converted to an extension method. For example:

public static void SetDate(this IList<Activity> aList)
{
    foreach(Activity current in anActivityList)
    {
        current.Date = DateTime.Now;
    }
}

The original function doesn't use any instance specific data or methods from the ActivityHelper class which makes it seem like it is in the incorrect place. Is this the correct time to write an extension method? What are the correct scenarios in which to create extension methods?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
brainimus
  • 10,586
  • 12
  • 42
  • 64
  • 1
    It seems that you are asking the wrong question. Whether you make it an extension method or not is largely unimportant. But you should almost certainly make it a **static** method either way. Your first method is non-static despite using no instance members; this is a (minor) design faux-pas. – Timwi Feb 01 '11 at 01:45
  • @Timwi Yes, I could very well make that method static and there is no specific reason why I didn't in this example. In either case I still feel though it is an awkward method. – brainimus Feb 01 '11 at 13:31
  • I find extension methods are best used when the target assembly or class is "closed for updates". I also find people mis-use extension methods to get around the Single Responsability Principle (SRP). In my opinion, Static Classes and Extension Methods are the most mis-used capabilities. – Prisoner ZERO Jul 02 '12 at 13:02
  • Not what you ask, but since it takes a little time to run through the loop, sometimes some of the activities will get a slightly different `Date` than others. If that is undesired, read `DateTime.Now` once before the loop, and use that value inside the loop so that all items get the same `DateTime`. – Jeppe Stig Nielsen May 23 '14 at 09:01

5 Answers5

12

Brad Adams has written about extension method design guidelines:

CONSIDER using extension methods in any of the following scenarios:

  • To provide helper functionality relevant to every implementation of an interface, if said functionality can be written in terms of the core interface. This is because concrete implementations cannot otherwise be assigned to interfaces. For example, the LINQ to Objects operators are implemented as extension methods for all IEnumerable types. Thus, any IEnumerable<> implementation is automatically LINQ-enabled.

  • When an instance method would introduce a dependency on some type, but such a dependency would break dependency management rules. For example, a dependency from String to System.Uri is probably not desirable, and so String.ToUri() instance method returning System.Uri would be the wrong design from a dependency management perspective. A static extension method Uri.ToUri(this string str) returning System.Uri would be a much better design.

Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
6

I think Extension methods are only appropriate if there is a compelling reason to make the method an extension method.

If the type is one you do not control, and the method should appear to be integral to the type, or if there is a compelling reason to not put the method directly on the type (such as creating an unwanted dependency) then an extension method could be appropriate.

Personally, if the expectation of the user of your API will already be to use the "ActivityHelper" class when working with collections of Activities, then I would probably not create an extension method for this. A standard, non-extension method will actually be a simpler API, since it's easily understood and discoverable. Extension methods are tricky from a usage standpoint - you're calling a method that "looks like" it exists somewhere other than where it actually exists. While this can simplify syntax, it reduces maintainability and discoverability.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 2
    True on the discoverability. If you don't know that the extension method exists, you'll never find it - doesn't appear in intellisense unless you have included the correct namespace. – Kirk Broadhurst Feb 01 '11 at 00:43
  • 1
    @Kirk: Yeah, and even when you know it 'exists somewhere', finding documentation, etc, can be tricky unless you know where it's coming from... – Reed Copsey Feb 01 '11 at 00:50
4

In my experience extension methods work best when they:

  • Don't have side-effects (most of the extension methods my team wrote that have side-effects, we ended up removing because they caused more problems than they helped)
  • Offer functionality that applies to every possible instance or value of the type they're extending. (Again citing an example from my team, string.NormalizeUrl() is not appropriate because not all strings are even URLs anyway)
Rex M
  • 142,167
  • 33
  • 283
  • 313
  • Not sure about the first one, Linq has a lot of side-effects. I agree that developers might be inclined to compose statements and omit safe coding practices, but obviously one needs to be aware of side-effects. – Yannick Motton Feb 01 '11 at 01:04
  • This isn't really responsive to the central question of whether one should use an extension method or a regular method in a "Helper" class. – Cody Gray - on strike Feb 01 '11 at 01:12
  • The second question the OP asked is of a more general nature. I imagine this is what Rex is replying to, and I am simply making a remark. – Yannick Motton Feb 01 '11 at 01:16
  • @Yannick the extension methods in LINQ are specifically designed *not* to have side-effects. – Rex M Feb 01 '11 at 11:48
  • That may be true for the Linq methods that defer execution, however the ones that consume the enumeration might even access the database. Are we talking about the same kinds of side-effects? – Yannick Motton Feb 01 '11 at 12:30
  • @Yannick "side effect" means modifying some existing value or state in addition to producing a value. None of the extension methods in LINQ have side-effects; they all project the original data into new sequences, leaving the original unmodified. – Rex M Feb 01 '11 at 12:34
  • I agree that the Linq extension methods themselves do not have side effects, however they can *cause* side effects. – Yannick Motton Feb 01 '11 at 12:44
0

Well i usually create extension methods to help me write codes which have a smooth flow. Its generally depends upon the method you are creating.

If you feel that the method should have already been in framework and is too general then its okay to create an extension method for that.

But you need to first analyze that the class you are extending will always will be in state that your extension method can handle.

For Guidelines here to Brad's Article

http://blogs.msdn.com/b/brada/archive/2009/01/12/framework-design-guidelines-extension-methods.aspx

Shekhar_Pro
  • 18,056
  • 9
  • 55
  • 79
0

In essence, Extension Methods provide a more fluent style syntax for Helper methods. This translates into the ability to seemingly add functionality to types or all implementations of interfaces.

However, I generally steer away from declaring Extension Methods with a void returntype, as I feel the usefulness of this fluent style syntax, which allows you to compose statements, is negated when the method in question doesn't return anything.

However, I guess it can be handy to have your methods picked up by IntelliSense... :-)

Yannick Motton
  • 34,761
  • 4
  • 39
  • 55