2009-06-05 13 views
9

Biorąc pod uwagę tę deklarację:Jaka jest różnica między tymi dwoma oświadczeniami?

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

namespace AProject.Helpers 
{ 
    public static class AClass 
    { 

i tę deklarację

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

    public static class AClass 
    { 

czy są jakieś różnice w jakimkolwiek sensie między nimi? Czy jest to tylko różnica w stylach kodowania?

Zawsze deklarowałem moje zajęcia jak pierwsze, ale ostatnio zauważyłem, że Microsoft uses the second.

+1

Wydaje się, że jest to duplikat pytania. Proszę zobaczyć doskonałą odpowiedź dla "[Should Usings być wewnątrz lub na zewnątrz przestrzeni nazw] [1]" [1]: http://stackoverflow.com/questions/125319/should-usings-be-inside- lub-poza-przestrzenią nazw – tsemer

Odpowiedz

26

W drugiej wersji dyrektywy użytkowania obowiązują tylko w deklaracji przestrzeni nazw.

W większości przypadków będziesz miał tylko jedną deklarację przestrzeni nazw:

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

Główną różnicą jest to, jeśli masz kilka nazw w tym samym pliku:

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

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

W tym przypadku za pomocą dyrektywy w deklaracji X przestrzeni nazw nie mają wpływu na kod wewnątrz deklaracji Y przestrzeni nazw i na odwrót.

Jednak to nie jedyna różnica - jest tam subtle case which Eric Lippert points out, gdzie może wpływać na kod, nawet z pojedynczą deklaracją przestrzeni nazw. (Zasadniczo, jeśli napiszesz using Foo; w deklaracji X przestrzeni nazw i istnieje przestrzeń nazw X.Foo, a także Foo, zachowanie się zmienia.Może to zostać naprawione przy użyciu aliasu przestrzeni nazw, np. using global::Foo;, jeśli naprawdę chcesz.)

Osobiście będę trzymać:

  • Jeden nazw deklarację na plik (i zwykle jeden rodzaj najwyższego poziomu na plik)
  • Korzystanie dyrektyw poza deklaracji przestrzeni nazw
+0

Świetna odpowiedź jak zwykle Jon. +1 –

6

Powoduje, że dyrektywy użytkowania są lokalne względem tego obszaru nazw, co w praktyce nie powinno mieć znaczenia, ponieważ (mam nadzieję) nie deklarujesz wielu typów w wielu przestrzeniach nazw w jednym pliku źródłowym.

Szczegóły here.

+0

Może to zrobić różnicę w przypadku krawędzi. Zobacz link w mojej odpowiedzi. –

0

Sądzę, że może istnieć powód do zastosowania drugiej alternatywy z perspektywy purystycznej, ponieważ bardziej oczywiste jest, jakie są zakresy dyrektyw using.

0

W pierwszym przykładzie deklaracje użycia są "globalne" dla całego pliku. W drugim przykładzie instrukcje użycia będą miały zastosowanie tylko do kodu owiniętego w bloku przestrzeni nazw.

Myślę, że jedyny czas, który naprawdę ma znaczenie, to to, że w pliku znajduje się więcej niż jedna przestrzeń nazw i chcesz ograniczyć obszar nazw, który ma dostęp do każdej deklaracji użycia.

2

drugi może być niejednoznaczny;

Górny jeden jasno swoją po tych nazw:

  • systemowe
  • System.Collections
  • System.Collections.Generic

podczas gdy druga będzie najpierw szukać te przestrzenie nazw:

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

I zamiast odnosić się do nich, jeśli są one znaleźć ... Jeśli nie, oboje będą odnosić się do tych samych przestrzeni nazw.

Bezpieczniej przepisać drugim byłoby:

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

A dla procesu, który Arjan wskazuje to uważane za złą praktyką zadeklarować usings wewnątrz przestrzeni nazw. Mogą być niejawnie nadpisane przez inną przestrzeń nazw.

1

Kolejna różnica między nimi powstaje podczas korzystania z LINQ-SQL i wygenerowanych klas danych w Internecie.Na przykład przykładowa baza danych Northwind; Początkowo otrzymasz:

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

Jeśli teraz chcemy przedłużyć częściowe zajęcia dodając własne Northwind.cs, masz

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

Amusingly, że jest błąd w kodzie generatora (MSLinqToSQLGenerator) - co oznacza, że ​​jeśli using dyrektywy to poza przestrzeni nazw (jak są one domyślnie), przerywa - z komunikatem:

The custom tool 'MSLinqToSQLGenerator' failed. Unspecified error

a plik zostanie usunięty Northwind.designer.cs. Koniec z kontekstem danych!

Jeśli jednak przenieść using dyrektyw wewnątrz przestrzeni nazw (i ponownie uruchomić narzędzie niestandardowej - kliknij prawym przyciskiem myszy w oknie Solution Explorer), to działa poprawnie.

A więc: nie jest to szczegół językowy - jest po prostu błędem w generatorze kodu; ale jest dość duża różnica między "działa poprawnie" a wygenerowany kod jest usuwany ...

Pamiętaj, że możesz to naprawić, po prostu nazywając swój plik czymś innym - na przykład NorthwindExtras.cs.

Zakręcony.

Powiązane problemy