I've been using extension methods quite a bit recently and have found a lot of uses for them. The only problem I have is remembering where they are and what namespace to use in order to get the extension methods.
However, I recently had a thought of writing the extension methods in the System namespace, System.Collections namespace or some other system namespace that makes sense. So for example, I've implemented the following.
namespace System
{
/// <summary>Various array extensions</summary>
public static class ArrayExtensions
{
/// <summary>Converts the array to a hex string</summary>
/// <param name="value">The value.</param>
/// <returns>The array as a hex string</returns>
public static string ToHexString(this byte[] value)
{
var hex = new StringBuilder(value.Length * 2);
foreach (byte b in value)
{
hex.AppendFormat("{0:X2}", b);
}
return hex.ToString();
}
}
}
Is this the correct thing to do?
An Extension Method should be in the same namespace as it is used or you need to import the namespace of the class by a using statement. You can give any name of for the class that has an Extension Method but the class should be static.
Select File > New > Project and select Visual C# and Console Application as shown below. Add the reference of the previously created class library to this project. In the above code, you see there is a static class XX with a method, NewMethod.
Rules to create Extension MethodCreate a static visible class which will hold the extension method(s). Make sure that the class is visible to the other class / Namespace by applying the appropriate access modifier. Create static Method(s) in the same Static Class with the same visibility level.
You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself.
From the Framework Design Guidelines (2nd Edition):
DO NOT put extension methods in the same namespace as the extended type, unless it is for adding methods to interfaces, or for dependency management.
While this doesn't explicitly cover your scenario, you should generally avoid extending a Framework namespace (or any namespace you have no control over) and opt instead to put those extensions in their own namespace. If you feel strongly about "grouping" the extensions (such that the collection extensions are together, etc.) then you could introduce a subnamespace. In your scenario, extension to the collections would go in a System.Collection.Extensions
namespace or a Company.Collections
or even a Company.Collections.Extension
namespace.
In order to use extension methods the namespace containing the sponsor class (the class that defines the extension methods) must be imported. If you add extension methods to one of the standard .NET Framework namespaces they will always (and implicitly) be available.
You should avoid augmenting namespaces over which you do not have primary control as future changes can break your code (by introducing duplicates, for example).
I tend to mimic the standard namespaces with a different root namespace that identifies all child namespaces as belonging to my work. The root namespace could be your name, your organisation's name, or something else that identifies the contents of that namespace as being yours.
For example, if you want to extend System.Collections
, you could use NickR.Collections
or NickR.System.Collections
.
The only thing that the namespace really affects with extension methods is visibility and discoverability - so it depends on whether you want the extension methods to always appear on that type or not. The framework design guidelines are intended primarily for public APIs and so, while it's generally a good idea to follow them, the rules are very much there to be broken for internal APIs when it makes sense.
For example, we do a lot of work with TimeSpan
objects throughout the codebase and there are no methods to multiply or divide these in the framework so we have added MultiplyBy
and DivideBy
extension methods, amongst others, and put them in the System
namespace because we want them accessible and discoverable wherever a TimeSpan
is used.
On the other hand we also do quite a bit of reflection work, operating on Type
objects, and there are a whole lot of extension methods that are very useful in specific areas but not generally, so these live in a OurCompany.Reflection
namespace so they have to be specifically imported.
So for internal APIs the decision boils down to "do I want this method to be available everywhere the type is available in our codebase?". If the answer is yes, then put it in the same namespace, otherwise put it somewhere else.
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