2011-02-04 10 views
8

Dado el siguiente fragmento de código:¿Por qué los tipos a los que se hace referencia fuera de un espacio de nombres deben estar totalmente calificados?

using System; 

using Foo = System.Int32; 

namespace ConsoleApplication3 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
     } 
    } 
} 

Si quito el "sistema". desde enfrente de Int32 en mi declaración para el alias tipo "Foo", obtengo un error de compilación. A pesar de que estoy usando el espacio de nombres del sistema en la parte superior del archivo, el compilador no puede encontrar un tipo "Int32" no calificado.

¿Por qué es eso?

+1

No son "tipos" fuera de un espacio de nombres. Solo se usa declaraciones de alias. 'class Program {static void Main (String [] args) {Int32 x = 0; }} 'fuera de un bloque de espacio de nombres funciona bien. –

Respuesta

10

Esto se debe a que la especificación C# dice que debe ser. Más específicamente, la sección 9.4.1 de la especificación de C# dice:

El orden en el que utilizando-alias-directivas se escriben no tiene ningún significado, y la resolución del espacio de nombres o nombre-tipo-referenciado por un using- alias-directive no se ve afectada por la directiva de uso de alias o por otras directivas de uso en la unidad de compilación o el cuerpo de espacio de nombres que contiene inmediatamente. En otras palabras, el espacio de nombre o nombre de tipo de una directiva de uso de alias se resuelve como si la unidad de compilación que lo contenía inmediatamente o el cuerpo del espacio de nombres no tuvieran instrucciones de uso. Sin embargo, una directiva using-alias puede verse afectada por las directivas extern-alias en la unidad de compilación o el cuerpo del espacio de nombres que contiene inmediatamente.

Dado que el orden no importa, el using System; no tiene ningún efecto en la directiva using-alias-directive. La sección específica que importa es: "el espacio de nombres o nombre de tipo de una directiva de uso de alias se resuelve como si la unidad de compilación que contiene inmediatamente o el cuerpo del espacio de nombres no tuviera instrucciones de uso".

+0

Esto también explica por qué "using Bar = System.Collections.Generic.List ;" en la siguiente línea tampoco funciona. ¡Gracias! –

+0

@Matt: De nada. En caso de duda, búsquelo en la especificación;) –

4

El spec (9.3) dice:

El alcance de una utilizando directiva se extiende sobre el espacio de nombres-miembro-declaraciones de su conteniendo inmediatamente unidad de compilación o espacio de nombres cuerpo. El alcance de una directiva de uso específicamente no incluye sus directivas de uso de pares. Por lo tanto, las directivas de uso de pares no se afectan entre sí, y el orden en que se escriben es insignificante.

Mueva su último using dentro del bloque de espacio de nombres y funcionará.

using System; 

namespace ConsoleApplication3 
{ 
    using Foo = Int32; 
+0

Sé que funciona dentro del bloque de espacio de nombres. Tenía curiosidad de por qué. ¿Está en alguna parte de la especificación? –

+1

La adición de una cita de la especificación es bienvenida, @Slaks, pero creo que tendré que dar la respuesta a Reed para publicar ese texto primero. +1 sin embargo! –

6

Porque las instrucciones de uso no se procesan en ningún orden en particular. El compilador no sabe procesar la primera línea antes del segundo.

Cuestiones relacionadas