2009-01-13 8 views
5

Recibí un error hoy al intentar hacer un poco de formato al código existente. Originalmente, el código había las using directivas declarada fuera del espacio de nombres:¿La ubicación de la directiva `using` hace la diferencia en C#?

using System.Collections.Generic; 
namespace MyNamespace 
{ 
    using IntPair = KeyValuePair<int, int>; 
} 

Cuando traté de insertar la directiva using dentro de la instrucción (para cumplir con las normas de StyleCop), que tiene un error en la directiva aliasing, y yo tuvo que calificarlo completamente:

namespace MyNamespace 
{ 
    using System.Collections.Generic; 
    //using IntPair = KeyValuePair<int, int>; // Error! 
    using IntPair = System.Collections.Generic.KeyValuePair<int, int>; // works 
} 

Me pregunto qué diferencia hay entre los dos casos? ¿Importa la ubicación de la directiva (import-style) using?

Respuesta

6

Solía ​​pensar que no importaba, pero siempre califico completamente usando comandos.

Editar: Controlado el C# spec, sección 9.4 dice que:

El alcance de una directiva utilizando específicamente no incluye el uso de su par-CEE. Por lo tanto, las directivas de uso de pares no se afectan entre sí, y el orden en que se escriben es insignificante.

Así que si System.Collections.Generic y KeyValuePair son tratados como iguales, entonces KeyValuePair va a ignorar System.Collections.Generic.

5

Sí, lo hace, en pequeña medida. Hay un caso marginal relacionado con los nombres locales/del alcance, consulte Eric Lippert's blog.

Para un ejemplo concreto (específico para el uso de alias):

using System; 
using Foo = Bar; 
public static class Bar { 
    public static void Test() { Console.WriteLine("outer"); } 
} 
namespace MyNamespace { 
    //using Foo = Bar; 

    public static class Bar { 
     public static void Test() { Console.WriteLine("inner"); } 
    } 
    static class Program { 
     static void Main() { 
      Foo.Test(); 
     } 
    } 
} 
1

Sí lo hace, tengo una working example a un question (Namespace collisions) similares.

En esencia, las reglas para la búsqueda de nombres son diferentes si la directiva using es global (fuera del espacio de nombres) o dentro del espacio de nombres cuando tiene mayor prioridad.

1

Esto es puramente informativo, es una de las respuestas que afirma que afecta el tiempo que se carga el conjunto; pero en realidad, los ensamblajes se cargan la primera vez que un método/tipo que los usa está JITted (o se accede a través de la reflexión, etc.).

Aquí hay un ejemplo que muestra que no hace diferencia; con la using en cualquier ubicación, la salida es el mismo: System.Core se carga como Bar obtiene compilados JIT:

pre-Bar 
System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
pre-Max 
Max: 5 
post-Max 
post-Bar 

ejemplo (dirigido en la línea de comandos, no en depurador; idealmente en configuración de liberación):

using System; 
//using System.Linq; 
namespace Foo { 
    using System.Linq; 
    class Program { 
     static Program() { 
      AppDomain.CurrentDomain.AssemblyLoad += (s, a) => { 
       Console.WriteLine(a.LoadedAssembly.FullName); 
      }; 
     } 
     static void Main() {    
      Console.WriteLine("pre-Bar"); 
      Bar(); 
      Console.WriteLine("post-Bar"); 
      Console.ReadLine(); 
     } 
     static void Bar() { 
      Console.WriteLine("pre-Max"); 
      int[] data = { 1, 2, 3, 4, 5 }; 
      Console.WriteLine("Max: " + Enumerable.Max(data)); 
      Console.WriteLine("post-Max"); 
     } 
    } 
} 
Cuestiones relacionadas