2009-06-05 15 views
9

Etant donné cette déclaration:Quelle est la différence entre ces deux déclarations?

using System; 
using System.Collections; 
using System.Collections.Generic; 

namespace AProject.Helpers 
{ 
    public static class AClass 
    { 

et cette déclaration

namespace AProject.Helpers 
{ 
    using System; 
    using System.Collections; 
    using System.Collections.Generic; 

    public static class AClass 
    { 

sont-il une différence dans tous les sens entre eux? Ou est juste une différence dans les styles de codage?

J'ai toujours utilisé pour déclarer mes classes comme le premier, mais j'ai récemment remarqué que Microsoft uses the second.

+1

Cela ressemble à une question en double. S'il vous plaît voir excellente réponse pour "[usings être à l'intérieur ou doit-dehors de l'espace de noms] [1]" [1]: http://stackoverflow.com/questions/125319/should-usings-be-inside- ou-outside-the-namespace – tsemer

Répondre

26

Dans cette dernière version, les directives using s'appliquent uniquement dans la déclaration d'espace de noms.

Dans la plupart des cas, vous aurez seulement une seule déclaration d'espace de noms:

// Using directives 
... 
namespace X 
{ 
    // Maybe more using directives 
    // Code 
} 
// End of file 

La principale différence est que si vous avez plusieurs espaces de noms dans le même fichier:

// Using directives 
... 
namespace X 
{ 
    // Maybe more using directives 
    // Code 
} 

namespace Y 
{ 
    // Maybe more using directives 
    // Code 
} 
// End of file 

Dans ce cas, l'utilisation de Les directives de la déclaration X de l'espace de noms n'affectent pas le code dans la déclaration Y de l'espace de noms, et vice versa.

Cependant, ce n'est pas la seule différence: il existe un subtle case which Eric Lippert points out où il peut affecter le code même avec une seule déclaration d'espace de nom. (Fondamentalement, si vous écrivez using Foo; dans la déclaration X de l'espace de noms, et qu'il y a un espace de noms X.Foo ainsi que Foo, le comportement change, ce qui peut être corrigé en utilisant un alias d'espace de noms, par exemple using global::Foo; si vous le voulez vraiment.)

Personnellement je bâton à:

  • Une déclaration namespace par fichier (et le plus souvent d'un type de niveau supérieur par fichier)
  • Utilisation des directives en dehors de la déclaration d'espace de noms
+0

Bonne réponse comme d'habitude Jon. +1 –

6

Il rend les directives using locales à cet espace de noms, ce qui en pratique ne devrait faire aucune différence puisque vous ne déclarez pas plusieurs types dans plusieurs espaces de noms dans un seul fichier source.

Détails here.

+0

Cela peut faire la différence dans un cas de bordure. Voir le lien dans ma réponse. –

0

Je suppose qu'il pourrait y avoir une raison d'utiliser la deuxième alternative d'un point de vue puriste, car cela rend plus clair la portée des directives using.

0

Dans le premier exemple, les déclarations using sont "globales" pour l'ensemble du fichier. Dans le second exemple, les instructions using ne s'appliqueront qu'au code enveloppé dans le bloc d'espace de nommage.

Je pense que la seule chose qui compte vraiment, c'est si vous avez plus d'un espace de noms dans le fichier, et que vous voulez limiter l'espace de noms qui a accès à chaque déclaration using.

2

Le la seconde peut être ambiguë;

Celui du haut fait clairement votre après ces espaces de noms:

  • système
  • System.Collections
  • System.Collections.Generic

Alors que le second sera d'abord chercher ces espaces de noms:

  • AProject.Helpers.System
  • AProject.Helpers.System.Collections
  • AProject.Helpers.System.Collections.Generic

Et se réfèrent à eux au lieu si on les trouve ... Dans le cas contraire, ils se référeront tous les deux aux mêmes espaces de noms.

Le plus sûr Réécriture du second serait:

namespace AProject.Helpers 
{ 
    using global::System; 
    using global::System.Collections; 
    using global::System.Collections.Generic; 
} 
0

Et pour le processus qui pointe Arjan sur, il est considéré comme une mauvaise pratique de déclarer usings l'intérieur de votre espace de noms. Ils peuvent être remplacés implicitement par un autre espace de noms.

1

Un autre important différence entre eux se produit lors de l'utilisation de LINQ-to-SQL et les classes datacontext générées.Par exemple, la base de données exemple Northwind; Au départ, vous obtenez:

  • Northwind.dbml
    • Northwind.dbml.layout
    • Northwind.designer.cs

Si vous voulez maintenant étendre les classes partielles en ajoutant votre Northwind.cs, vous obtenez

  • Northwind.dbml
    • Northwind.dbml.layout
    • Northwind.designer.cs
    • Northwind.cs

amusante, il y a une erreur dans le code-générateur (MSLinqToSQLGenerator) - ce qui signifie que si le using les directives sont en dehors l'espace de noms (comme ils sont par défaut), il se casse - avec le message:

The custom tool 'MSLinqToSQLGenerator' failed. Unspecified error

Et le fichier Northwind.designer.cs est supprimé. Plus de données-contexte!

Cependant, si vous déplacez les using directives à l'intérieur l'espace de noms (et re-exécuter l'outil personnalisé - clic droit dans l'explorateur de solution), il fonctionne correctement. Donc: ce n'est pas un détail de la langue - c'est simplement un bug dans le générateur de code; mais il y a une grande différence entre "fonctionne correctement" et le code généré est supprimé ...

Notez que vous pouvez également résoudre ce problème simplement en appelant votre fichier quelque chose de différent - comme NorthwindExtras.cs.

Freaky.

Questions connexes