When is it correct to create an extension method?
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 =开发者_如何学C 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?
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.
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.
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)
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
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... :-)
精彩评论