Ce fil a déjà d'excellentes réponses, mais je pense que je peux apporter un peu plus de détails avec cette réponse supplémentaire.
Tout d'abord, rappelez-vous qu'une déclaration d'espace de noms avec des points, comme:
namespace MyCorp.TheProduct.SomeModule.Utilities
{
...
}
est entièrement équivalent à:
namespace MyCorp
{
namespace TheProduct
{
namespace SomeModule
{
namespace Utilities
{
...
}
}
}
}
Si vous le vouliez, vous pourriez mettre des using
directives à tous ces niveaux. (Bien sûr, nous voulons avoir des using
s dans un seul endroit, mais ce serait légal selon la langue.)
La règle de résolution du type implicite peut être énoncée de la manière suivante: commencez par rechercher la "portée" la plus interne pour une correspondance, si rien n'y est trouvé, sortez d'un niveau à la portée suivante et recherchez-y, et ainsi de suite , jusqu'à ce qu'une correspondance soit trouvée. Si, à un certain niveau, plusieurs correspondances sont trouvées, si l'un des types provient de l'assembly actuel, sélectionnez-le et émettez un avertissement du compilateur. Sinon, abandonnez (erreur de compilation).
Maintenant, soyons explicites sur ce que cela signifie dans un exemple concret avec les deux principales conventions.
(1) Avec des utilisations à 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, pour savoir de quel type il Ambiguous
s'agit, la recherche se déroule dans cet ordre:
- Types imbriqués à l'intérieur
C
(y compris les types imbriqués hérités)
- Types dans l'espace de noms actuel
MyCorp.TheProduct.SomeModule.Utilities
- Types dans l'espace de noms
MyCorp.TheProduct.SomeModule
- Types dans
MyCorp.TheProduct
- Types dans
MyCorp
- Types dans l' espace de noms nul (l'espace de noms global)
- Types
System
, System.Collections.Generic
, System.Linq
, MyCorp.TheProduct.OtherModule
, MyCorp.TheProduct.OtherModule.Integration
etThirdParty
L'autre convention:
(2) Avec des utilisations à 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;
}
}
Maintenant, recherchez le type Ambiguous
dans cet ordre:
- Types imbriqués à l'intérieur
C
(y compris les types imbriqués hérités)
- Types dans l'espace de noms actuel
MyCorp.TheProduct.SomeModule.Utilities
- Types
System
, System.Collections.Generic
, System.Linq
, MyCorp.TheProduct
, MyCorp.TheProduct.OtherModule
, MyCorp.TheProduct.OtherModule.Integration
etThirdParty
- Types dans l'espace de noms
MyCorp.TheProduct.SomeModule
- Types dans
MyCorp
- Types dans l' espace de noms nul (l'espace de noms global)
(Notez que cela MyCorp.TheProduct
faisait partie de "3." et n'était donc pas nécessaire entre "4." et "5.".)
Remarques finales
Peu importe si vous placez les utilisations à l'intérieur ou à l'extérieur de la déclaration d'espace de noms, il est toujours possible que quelqu'un ajoute plus tard un nouveau type avec un nom identique à l'un des espaces de noms qui ont une priorité plus élevée.
En outre, si un espace de noms imbriqué a le même nom qu'un type, il peut provoquer des problèmes.
Il est toujours dangereux de déplacer les utilisations d'un emplacement à un autre car la hiérarchie de recherche change et un autre type peut être trouvé. Par conséquent, choisissez une convention et respectez-la, de sorte que vous n'aurez jamais à déplacer les utilisations.
Les modèles de Visual Studio, par défaut, mettent les utilisations à 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 des utilisations à l' extérieur est que vous pouvez ensuite utiliser les directives using pour un attribut global, par exemple [assembly: ComVisible(false)]
au lieu de [assembly: System.Runtime.InteropServices.ComVisible(false)]
.