2011-02-04 13 views
8

Biorąc pod uwagę następujący fragment kodu: "System"Dlaczego typy przywoływane poza obszarem nazw muszą być w pełni kwalifikowane?

using System; 

using Foo = System.Int32; 

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

Jeśli usunąć z przed Int32 w mojej deklaracji dla aliasu typu "Foo", dostaję błąd kompilatora. Pomimo tego, że używam przestrzeni nazw System u góry pliku, kompilator nie może znaleźć niewykwalifikowanego typu "Int32".

Dlaczego tak jest?

+1

Nie jest to "typ" poza obszarem nazw. To tylko przy użyciu deklaracji aliasów. 'class Program {static void Main (String [] args) {Int32 x = 0; }} 'poza blokiem przestrzeni nazw działa dobrze. –

Odpowiedz

10

Dzieje się tak, ponieważ specyfikacja C# mówi, że tak być musi. Dokładniej, sekcja 9.4.1 w specyfikacji C# mówi:

Kolejność, w jakiej using-alias-dyrektyw są napisane nie ma znaczenia, a rozdzielczość-or-nazwa-typu przestrzeni nazw odwołuje się using- alias-dyrektywa nie jest zależna od samej dyrektywy-używania-alias ani od innych dyrektyw-użytkowych w bezpośrednio zawierającej jednostkę kompilacji lub treść przestrzeni nazw. Innymi słowy, nazwa przestrzeni nazw lub typu dyrektywy aliasów użycia jest rozwiązywana tak, jakby natychmiast zawierająca jednostkę kompilacji lub treść przestrzeni nazw nie miała żadnych dyrektyw użycia. Na dyrektywę alias-użytkowanie mogą mieć wpływ dyrektywy zewnętrzne-alias w bezpośrednio zawierającej jednostkę kompilacji lub treść przestrzeni nazw.

Ponieważ zamówienie nie ma znaczenia, using System; nie ma wpływu na dyrektywę aliasów użytkowania. Szczególna sekcja, która ma znaczenie, jest następująca: "nazwa przestrzeni nazw lub typu dyrektywy aliasów użycia jest rozwiązana tak, jakby natychmiast zawierająca jednostkę kompilacji lub treść przestrzeni nazw nie miała żadnych dyrektyw" ".

+0

To wyjaśnia również, dlaczego "przy użyciu Bar = System.Collections.Generic.List ;" na następnej linii też nie działa. Dzięki! –

+0

@Matt: Nie ma za co. W razie wątpliwości sprawdź to w specyfikacji;) –

4

The spec (9.3) mówi:

Zakres using Dyrektywa rozciąga się na przestrzeni nazw państwie deklaracji jej bezpośrednio zawierającego ciała jednostki kompilacji lub przestrzeni nazw. Zakres dyrektywy use-specific w szczególności nie obejmuje dyrektyw peer-use. W związku z tym dyrektywy używane przez peer nie wpływają na siebie nawzajem, a kolejność, w jakiej są napisane, jest nieistotna.

Przenieś swój ostatni using wewnątrz bloku przestrzeni nazw i będzie działać.

using System; 

namespace ConsoleApplication3 
{ 
    using Foo = Int32; 
+0

Wiem, że działa wewnątrz bloku przestrzeni nazw - byłem tylko ciekawy, dlaczego. Czy jest gdzieś w specyfikacji? –

+1

Dodanie cytatu ze specyfikacji jest mile widziane, @Slaks, ale myślę, że będę musiał dać odpowiedź Reedowi na umieszczenie tego tekstu w pierwszej kolejności. +1! –

6

Ponieważ stosowanie instrukcji nie jest przetwarzane w określonej kolejności. Kompilator nie wie, aby przetworzyć pierwszą linię przed drugą.

Powiązane problemy