可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Do you use a global, catchall namespace for all of your extension methods, or do you put the extension methods in the same namespace as the class(es) they extend?
Or do you use some other method, like an application or library-specific namespace?
I ask because I have a need to extend System.Security.Principal.IIdentity
, and putting the extension method in the System.Security.Principal
namespace seems to make sense, but I've never seen it done this way.
回答1:
I would recommend putting all your extension methods in a single namespace (incidentally this is also what Microsoft did with Linq by putting them in a single class 'Extensions' inside the 'System.Linq' namespace).
Since Visual Studio provides no clues as to how to locate an extension method that you want to use, it reduces confusion by only having to remember one namespace.
回答2:
Put your extensions in the same namespace as the classes they extend. That way, when you use the class, the extensions are available to you.
- If you are writing a extension for Uri, put the extension in System.
- If it's a extension for DataSet, put it in System.Data.
Also, Microsoft says this about extension methods:
In general, we recommend that you
implement extension methods sparingly
and only when you have to. Whenever
possible, client code that must extend
an existing type should do so by
creating a new type derived from the
existing type.
For more info about extension methods, see the MSDN page about extension methods.
回答3:
If they're extension methods used throughout the solution (e.g. over 60% of classes), I put them in the base namespace of the solution (since they'll be automatically imported being in a parent namespace, no importing the common stuff every time).
In this category, things like:
.IsNullOrEmpty(this string value)
and .HasValue(this string value)
However, if they're very specific and rarely used, I put them in a BaseNamepace.Extensions
namespace so they must be manually imported and don't show in intellisense cluttering things up everywhere.
回答4:
I upvoted the answer from user276695 which seemed the simplest solution. However I found an even better solution: no namespace at all. You can put a static class with extension methods at the very root of a file, without wrapping any namespace declaration around it. Then the extension methods will be available without having to import/using any namespace.†
I'm slightly worried about being down-voted from namespace nazis. But I feel compelled to champion a slightly unorthodox position. At least in my line of work (IT) I find that most of my custom tools are easier to maintain without namespaces, and placing everything in one giant anonymous namespace. I'm sure there are other programming universes where this would not work as well. But perferences & circumstances being different, I just wanted to point out that you can in fact declare classes without namespaces, even classes with extension methods - for those who also find a giant anonymous namespace better.
† You also get to save one level of indentation. :-) And even with 3 giant monitors I'm always looking for ways to save screen real-estate.
回答5:
My practice is to put the extensions in a namespace that is different from yet clearly identifies the source namespace that I'm extending.
Generally, I create a namespace by prefixing my "company name" part of the namespace path in front of the namespace I'm extending, and then suffix it with ".Extensions"
For example, if I'm extending (for no good reason) ::System.Text.StringBuilder
because it's sealed, then I will put my extensions in the namespace ::CodeCharm.System.Text.Extensions
.
That's a rule of thumb for when I make extensions that I suspect I could re-use those extensions in other solutions.
回答6:
If you put them in a higher namespace than your current, they will be visible automatically.
So if you have namespaces for projects like:
AdventureWorksInc.Web
AdventureWorksInc.Logic
AdventureWorksInc.DataAccess
Then declare your extension directly in:
namespace AdventureWorksInc
{
public static class HtmlHelpers
{
public static string AutoCloseHtmlTags(this string html)
{
//...
}
}
}
This extension method will show up whenever you are writing code in any sub name space of AdventureWorksInc without the need for a using statement.
However, the above extension demonstrates a possible downside. Due to the fact that it operates on strings, it will now show up as an extension method for all strings, including those that aren't really HTML. This is actually not an issue with namespace scoping, but simply a misuse of an extension method. This should be a regular static that requires a standard parameter so the call is explicit.
Generally well designed extension methods with appropriately typed parameters will not show up on types that it would never apply.