A translation of one of the answers should 'using' statements be inside or outside the namespace?
To begin with, pay attention to the fact that the namespace is defined as follows:
namespace MyCorp.TheProduct.SomeModule.Utilities { ... }
equivalent to defining multiple nested namespaces:
namespace MyCorp { namespace TheProduct { namespace SomeModule { namespace Utilities { ... } } } }
If you connect an assembly outside the space, then it will be visible inside all spanning spaces. The search for a specific type can be expressed like this: firstly, the search for a match in the innermost "scope", if nothing was found there to go up one level and search there, and so on, until a match is found. If there is more than one match at any level, you will get a compiler warning. If not found, issue an error at compile time.
Now, let's be more clear about what this means on a concrete example with two main conventions.
(1) With usings outside:
using System; using System.Collections.Generic; using System.Linq; //using MyCorp.TheProduct; <-- uncommenting this would change nothing using MyCorp.TheProduct.OtherModule; using MyCorp.TheProduct.OtherModule.Integration; using ThirdParty; namespace MyCorp.TheProduct.SomeModule.Utilities { class C { Ambiguous a; } }
In the above case, to find out the type of Ambiguous
, the search goes in the following order:
- Nested types inside
C
(including inherited nested types) - Types in the current namespace
MyCorp.TheProduct.SomeModule.Utilities
- Types in the
MyCorp.TheProduct.SomeModule
- Types in
MyCorp.TheProduct
- Types in
MyCorp
- Types in the global namespace
- Types in
System
, System.Collections.Generic
, System.Linq
, MyCorp.TheProduct.OtherModule
, MyCorp.TheProduct.OtherModule.Integration
and ThirdParty
Other convention:
(2) With usings inside:
namespace MyCorp.TheProduct.SomeModule.Utilities { using System; using System.Collections.Generic; using System.Linq; using MyCorp.TheProduct; // MyCorp can be left out; this using is NOT redundant using MyCorp.TheProduct.OtherModule; // MyCorp.TheProduct can be left out using MyCorp.TheProduct.OtherModule.Integration; // MyCorp.TheProduct can be left out using ThirdParty; class C { Ambiguous a; } }
Now search by type Ambiguous
goes in the following order:
- Nested types inside
C
(including inherited nested types) - Types in the current namespace
MyCorp.TheProduct.SomeModule.Utilities
- Types in
System
, System.Collections.Generic
, System.Linq
, MyCorp.TheProduct
, MyCorp.TheProduct.OtherModule
, MyCorp.TheProduct.OtherModule.Integration
and ThirdParty
- Types in the
MyCorp.TheProduct.SomeModule
- Types in
MyCorp
- Types in the global namespace
(Note that MyCorp.TheProduct
was part of "3." and, therefore, is not required between "4." and "5."
Concluding remarks
Regardless of whether you are using
inside or outside a namespace declaration, there is always a chance that someone later adds a new type with the same name to one of the spaces, which has a higher priority.
In addition, if the nested namespace has the same name as the type, this can cause problems.
It is always dangerous to move using
from one place to another, as the search hierarchy changes, and another type can be found. So choose one convention and stick to it so that you never have to move using
.
The default Visual Studio
template, by default, is using
outside of the namespace (for example, if you create a new class in a new file).
One (tiny) advantage of using
outside the namespace, you can use directives for a global attribute, for example [assembly: ComVisible(false)]
instead of [assembly: System.Runtime.InteropServices.ComVisible(false)]
.