2009-06-05 9 views
9

Teniendo en cuenta esta declaración:¿Cuál es la diferencia entre estas dos declaraciones?

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

namespace AProject.Helpers 
{ 
    public static class AClass 
    { 

y esta declaración

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

    public static class AClass 
    { 

¿hay alguna diferencia en cualquier sentido entre ellos? ¿O solo es una diferencia en los estilos de codificación?

Yo siempre solía declarar mis clases como la primera, pero recientemente noté que Microsoft uses the second.

+1

Parece una pregunta duplicada. Por favor, véase la respuesta excelente para "[deberían usings sea dentro o fuera del espacio de nombres] [1]" [1]: http://stackoverflow.com/questions/125319/should-usings-be-inside- or-outside-the-namespace – tsemer

Respuesta

26

En esta última versión, las directivas de uso solo se aplican dentro de la declaración del espacio de nombres.

En la mayoría de los casos, sólo tendrá una única declaración de espacio:

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

La principal diferencia es si usted tiene varios espacios de nombres en el mismo archivo:

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

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

En este caso, el uso de las directivas en la declaración X del espacio de nombres no afectan el código dentro de la declaración Y del espacio de nombres, y viceversa.

Sin embargo, esa no es la única diferencia: hay un subtle case which Eric Lippert points out en el que puede afectar el código incluso con una sola declaración de espacio de nombres. (Básicamente si escribe using Foo; dentro de la declaración X del espacio de nombres, y hay un espacio de nombres X.Foo, así como Foo, el comportamiento cambia. Esto puede remediarse usando un alias de espacio de nombres, por ejemplo using global::Foo; si realmente lo desea.)

Personalmente me gustaría poner:

  • Un espacio de nombres declaración por archivo (y por lo general un tipo de nivel superior por archivo)
  • Uso de las directivas fuera de la declaración de espacio de nombres
+0

Gran respuesta como de costumbre Jon. +1 –

6

Hace que las directivas de uso sean locales para ese espacio de nombres, lo que en la práctica no debería hacer ninguna diferencia ya que (afortunadamente) no se declaran varios tipos en múltiples espacios de nombres en un solo archivo fuente.

Detalles here.

+0

Puede marcar la diferencia en un caso marginal. Ver el enlace en mi respuesta. –

0

Supongo que puede haber una razón para usar la segunda alternativa desde una perspectiva purista, ya que deja más claro cuál es el alcance de las directivas using.

0

En el primer ejemplo, las declaraciones de uso son "globales" para todo el archivo. En el segundo ejemplo, las instrucciones de uso solo se aplicarán al código envuelto en el bloque de espacio de nombres.

Creo que el único momento en el que esto realmente importa es si tiene más de un espacio de nombres en el archivo y desea limitar el espacio de nombres que tiene acceso a cada declaración de uso.

2

El segundo puede ser ambiguo;

La de arriba deja claro que su después de estos espacios de nombres:

  • sistema
  • System.Collections
  • System.Collections.Generic

mientras que el segundo buscará primero estos espacios de nombres:

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

y se refieren a ellos en su lugar si los encuentran ... Si no, ambos se referirán a los mismos espacios de nombres.

La reescritura más seguro de la segunda sería:

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

Y para el proceso que Arjan señala, se considera que es una mala práctica de declarar usings dentro de su espacio de nombres. Pueden ser reemplazados implícitamente por otro espacio de nombres.

1

Otro importante la diferencia entre ellos surge cuando se utiliza LINQ-to-SQL y las clases de datos de contexto generados.Por ejemplo, la base de datos de ejemplo Northwind; Inicialmente, se obtiene:

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

Si ahora desea extender las clases parciales añadiendo su propio Northwind.cs, se obtiene

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

Divertidamente, hay un error en el código-generador (MSLinqToSQLGenerator) - lo que significa que si el using las directivas son fuera el espacio de nombres (como son por defecto), se rompe - con el mensaje:

The custom tool 'MSLinqToSQLGenerator' failed. Unspecified error

y el archivo se elimina Northwind.designer.cs. ¡No más contexto de datos!

Sin embargo, si mueve las directivas usingdentro el espacio de nombres (y volver a ejecutar la herramienta personalizada - haga clic derecho en el explorador de soluciones), funciona correctamente.

Entonces, esto no es un detalle del lenguaje, es simplemente un error en el generador de código; pero hay una gran diferencia entre "funciona correctamente" y el código generado se borra ...

Nota: también puede solucionar esto simplemente llamando a su archivo algo diferente, como NorthwindExtras.cs.

Freaky.

Cuestiones relacionadas