Let's say I have a need for a simple private helper method, and intuitively in the code it would make sense as an extension method. Is there any way to encapsulate that helper to the only class that actually needs to use it?
For example, I try this:
class Program
{
static void Main(string[] args)
{
var value = 0;
value = value.GetNext(); // Compiler error
}
static int GetNext(this int i)
{
return i + 1;
}
}
The compiler doesn't "see" the GetNext()
extension method. The error is:
Extension method must be defined in a non-generic static class
Fair enough, so I wrap it in its own class, but still encapsulated within the object where it belongs:
class Program
{
static void Main(string[] args)
{
var value = 0;
value = value.GetNext(); // Compiler error
}
static class Extensions
{
static int GetNext(this int i)
{
return i + 1;
}
}
}
Still no dice. Now the error states:
Extension method must be defined in a top-level static class; Extensions is a nested class.
Is there a compelling reason for this requirement? There are cases where a helper method really should be privately encapsulated, and there are cases where the code is a lot cleaner and more readable/supportable if a helper method is an extension method. For cases where these two intersect, can both be satisfied or do we have to choose one over the other?
Is there a compelling reason for this requirement?
That's the wrong question to ask. The question asked by the language design team when we were designing this feature was:
Is there a compelling reason to allow extension methods to be declared in nested static types?
Since extension methods were designed to make LINQ work, and LINQ does not have scenarios where the extension methods would be private to a type, the answer was "no, there is no such compelling reason".
By eliminating the ability to put extension methods in static nested types, none of the rules for searching for extension methods in static nested types needed to be thought of, argued about, designed, specified, implemented, tested, documented, shipped to customers, or made compatible with every future feature of C#. That was a significant cost savings.
I believe the best you can get in general case is internal static
class with internal static
extension methods. Since it will be in your own assembly the only people you need to prevent usage of the extension are authors of the assembly - so some explicitly named namespace (like My.Extensions.ForFoobarOnly
) may be enough to hint to avoid misuse.
The minimal internal
restriction covered in implement extension article
The class must be visible to client code ... method with at least the same visibility as the containing class.
Note: I would make extension public anyway to simplify unit testing, but put in some explicitly named namespace like Xxxx.Yyyy.Internal
so other users of the assembly would not expect the methods to be supported/callable. Essentially rely on convention other than compile time enforcement.
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