views:

69

answers:

2

I've been using extension methods a lot recently to help make my code be more fluent, but I keep running into situations where I can't limit the exposure of the functionality I've created in the way I'd like.

Say I have some code like this (completely made up example):

var liveSet = allitems.Where(x => x.Status == Status.Live).Select(x => x.Name);
var deadSet = allitems.Where(x => x.Status == Status.Dead).Select(x => x.Name);
var zombieSet = allitems.Where(x => x.Status == Status.Neither).Select(x => x.Name);

I'd like to make this more fluent, and stop repeating myself:

var liveSet = allitems.SelectNameWhere(x => x.Status == Status.Live);
...

But I consider this to be a helper method, not a true extension and so I would like to limit its usage in the same way as I can a private method:

//In the same class
private static IEnumerable<string> SelectNameWhere(
                   this IEnumerable<Element> items,
                   Func<Element, bool> predicate)
...

Unfortunately I can't do this because the class that holds the extension method must be static. Okay, not the end of the world, I'll nest a private static class to hold the method... Of course I can't do that either, so I'm left either exposing this method to at least an internal level, or removing the nice, fluent, nature of my code:

var liveSet = SelectNameFrom(allItems, x => x.Status == Status.Live);
...

These limitations on where you can declare an extension method seem fairly arbitrary to me, but I assume they have good logical or technical reasons. If so, what are they?

A: 

The fact that you do not want to expose the extension method should be a clear indication that your function should not be an extension method. Extension methods are intended to expose existing functionality on a type in a more friendly way.

jvanrhyn
Isn't my example exposing existing functionality in a more friendly way? If it was in a separate, public extension class I don't believe anyone would claim it wasn't a valid use for extension methods. It's just an extension method that I don't want cluttering up my intellisense outside of the class that uses it.
Martin Harris
You are correct, it is a valid use of an extension method. But you now want to change the way the extension methods are implemented to accommodate convenience in the IDE, which is not a good reason for wanting it. You can after all, code C# using notepad.
jvanrhyn
+1  A: 

The main reason that extension method classed are not nested is to make it easier for the compiler to find them (the same reason caused them to be restricted to static classes). Right now the compiler has to scan all static classes under a namespace to find the methods. If nesting or using them in all classes would be permitted then the compiler's job would be much harder. Also that could lead to name collisions.

Eg.:

public static class Foo
{
   public static void DoStuff(this object param)
   {
   }
   public static class Bar
   {
      public static void DoStuff(this object param)
      {
      }
   }
}
AZ