Ce thread a déjà de grandes réponses, mais je sens que je peux apporter un peu plus en détail de cette réponse supplémentaire.
Tout d'abord, rappelez-vous qu'une déclaration d'espace de noms avec des périodes, comme:
namespace MyCorp.TheProduct.SomeModule.Utilities
{
...
}
est totalement équivalente à:
namespace MyCorp
{
namespace TheProduct
{
namespace SomeModule
{
namespace Utilities
{
...
}
}
}
}
Si vous vouliez, vous pourriez mettre using
directives sur l'ensemble de ces niveaux. (Bien sûr, nous voulons using
s dans un seul endroit, mais il serait possible de le faire en fonction de la langue.)
La règle de résolution qui est de type implicite, peut-être vaguement indiqué comme ceci: d'Abord la recherche à l'intérieur de la plupart des "portée" pour un match, si rien n'est trouvé là, vous passez d'un niveau à la prochaine portée et de la recherche, et ainsi de suite, jusqu'à ce qu'une correspondance soit trouvée. Si, à un niveau plus qu'une correspondance est trouvée, si l'un de ces types sont de l'actuelle assemblée, choisir que l'un et émettre un avertissement du compilateur. Sinon, abandonner (erreur de compilation).
Maintenant, soyons clair sur ce que cela signifie dans un exemple concret avec les deux grandes conventions.
(1) Avec l'usage à l'extérieur:
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;
}
}
Dans le cas ci-dessus, à savoir quel type Ambiguous
est, la recherche va dans cet ordre:
- Les types imbriqués à l'intérieur d'
C
(y compris hérité les types imbriqués)
- Types dans l'espace de noms courant
MyCorp.TheProduct.SomeModule.Utilities
- Types dans l'espace de noms
MyCorp.TheProduct.SomeModule
- Types en
MyCorp.TheProduct
- Types en
MyCorp
- Les Types de l' null espace de noms (namespace global)
- Types en
System
, System.Collections.Generic
, System.Linq
, MyCorp.TheProduct.OtherModule
, MyCorp.TheProduct.OtherModule.Integration
, et ThirdParty
L'autre convention:
(2) Avec l'usage à l'intérieur:
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;
}
}
Désormais, la recherche pour le type Ambiguous
va dans cet ordre:
- Les types imbriqués à l'intérieur d'
C
(y compris hérité les types imbriqués)
- Types dans l'espace de noms courant
MyCorp.TheProduct.SomeModule.Utilities
- Types en
System
, System.Collections.Generic
, System.Linq
, MyCorp.TheProduct
, MyCorp.TheProduct.OtherModule
, MyCorp.TheProduct.OtherModule.Integration
, et ThirdParty
- Types dans l'espace de noms
MyCorp.TheProduct.SomeModule
- Types en
MyCorp
- Les Types de l' null espace de noms (namespace global)
(À noter qu' MyCorp.TheProduct
a été une partie de "3" et n'a donc pas besoin, entre les "4." "5.".)
Remarques finales
Peu importe si vous mettez l'usage à l'intérieur ou à l'extérieur de la déclaration d'espace de noms, il y a toujours la possibilité que quelqu'un, plus tard, ajoute un nouveau type avec un nom identique à l'un des espaces de noms qui sont prioritaires.
Aussi, si un espace de noms imbriqué a le même nom qu'un type, il peut causer des problèmes.
Il est toujours dangereux de déplacer l'usage d'un endroit à l'autre à la recherche de modifications de la hiérarchie, et d'un autre type peut être trouvé. Par conséquent, choisir une convention et s'y tenir, de sorte que vous n'aurez pas à déplacer jamais l'usage.
Visual Studio modèles, par défaut, mettez l'usage à l'extérieur de l'espace de noms (par exemple si vous faites VS générer une nouvelle classe dans un nouveau fichier).
Un (petit) avantage d'avoir l'usage à l'extérieur , c'est que vous pouvez alors utiliser l'aide de directives pour un attribut global, par exemple [assembly: ComVisible(false)]
au lieu de [assembly: System.Runtime.InteropServices.ComVisible(false)]
.