Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a good reason why extension method classes can't be nested?

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?

like image 906
Martin Harris Avatar asked Nov 25 '25 16:11

Martin Harris


1 Answers

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)
      {
      }
   }
}
like image 88
Adrian Zanescu Avatar answered Nov 28 '25 15:11

Adrian Zanescu