In my previous post I talked about the basics of extension method. Obviously you can define an extension method on any type but be careful. Because extension method are public member of public class their scope is very wide. After a while you can end up so many added method to the base type that it would make the intellisense unusable.
One way to control the scope is to target the type or interface that will best suit the need. In fact it is usually better to use interface than concrete class whenever possible. Of course this will probably extend the number of types on which the extension apply but it will be based on its capabilities instead of its implementation. For example linq use this concept a lot by extending IEneumrable<T> interface. Take for example the “Where” extension method:
public static class Enumerable { // ... public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { // ... } // ... }
var processes = System.Diagnostics.Process.GetProcesses(); var query = processes .Where(proc => proc.Modules.Count > 3) .OrderByDescending(proc => proc.VirtualMemorySize64) .Take(10) .Select(proc => proc);
All that to say that it is better to use interfaces as a source type for extension method. We can use extension method to transform a na interface into another one. For example the “ToLookup” extension method takes an “IEnumerable<TSource>” and convert it to an “ILookup<TKey, TSource>”. This transformation adds an indexer based on a key for any IEnumerable types.
var processes = Process.GetProcesses(); var idxProcesses = processes.ToLookup(proc => proc.Id); using (var proc = idxProcesses[3119].SingleOrDefault()) { Console.WriteLine(proc.ProcessName); }
As you can see extension methods provides endless possibilities if used carefully.
2 comments:
I think you've got the IEnumerable[T] example somwhat back to front. The extension methods aren't implemented on this interface to limit the scope; in fact precisely the opposite they are implemented here is because it is the *least specific* type, so as to give them the *widest possible scope* of anything that is enumerable!
@greg: You are right. I updated the post. I was thinking of something else when I wrote that.
Post a Comment