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?
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)
{
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With