Czy dyrektywy „używające” powinny znajdować się w przestrzeni nazw, czy poza nią?

2060

Używam StyleCop na pewnym kodzie C # i ciągle zgłasza, że ​​moje usingdyrektywy powinny znajdować się w przestrzeni nazw.

Czy istnieje techniczny powód, aby umieścić usingdyrektywy w środku zamiast poza przestrzenią nazw?

benPearce
źródło
4
Czasami robi to różnicę, gdy stawiasz zastosowania: stackoverflow.com/questions/292535/linq-to-sql-designer-bug
gius
82
Tylko w celach informacyjnych istnieją implikacje wykraczające poza kwestię wielu klas na plik, więc jeśli nie znasz tego pytania, czytaj dalej.
Charlie,
3
@ user-12506 - nie działa to zbyt dobrze w średnim i dużym zespole programistycznym, w którym wymagany jest pewien poziom spójności kodu. I jak wspomniano wcześniej, jeśli nie rozumiesz różnych układów, możesz znaleźć przypadki krawędzi, które nie działają zgodnie z oczekiwaniami.
benPearce
34
Terminologia: to nie są using stwierdzenia ; to są using dyrektywy . Z usingdrugiej strony, instrukcja jest strukturą językową, która występuje wraz z innymi instrukcjami wewnątrz ciała metody itp. Na przykład, using (var e = s.GetEnumerator()) { /* ... */ }instrukcja jest luźno taka sama jak var e = s.GetEnumerator(); try { /* ... */ } finally { if (e != null) { e.Dispose(); } }.
Jeppe Stig Nielsen,
1
Jeśli nikt nie wspomniał o tym wcześniej, tak naprawdę Microsoft również zaleca umieszczanie usinginstrukcji w namespacedeklaracjach, w swoich wewnętrznych
wytycznych dotyczących

Odpowiedzi:

2132

W rzeczywistości istnieje (subtelna) różnica między nimi. Wyobraź sobie, że masz następujący kod w pliku File1.cs:

// File1.cs
using System;
namespace Outer.Inner
{
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

Teraz wyobraź sobie, że ktoś dodaje do projektu kolejny plik (File2.cs), który wygląda następująco:

// File2.cs
namespace Outer
{
    class Math
    {
    }
}

Kompilator wyszukuje Outerprzed spojrzeniem na te usingdyrektywy poza przestrzenią nazw, więc znajduje Outer.Mathzamiast System.Math. Niestety (a może na szczęście?) Nie Outer.Mathma PIczłonka, więc File1 jest teraz zepsuty.

Zmienia się to, jeśli umieścisz usingwewnątrz deklaracji przestrzeni nazw, co następuje:

// File1b.cs
namespace Outer.Inner
{
    using System;
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

Teraz kompilator wyszukuje Systemprzed wyszukiwaniem Outer, znajduje System.Mathi wszystko jest w porządku.

Niektórzy twierdzą, że Mathmoże to być zła nazwa dla klasy zdefiniowanej przez użytkownika, ponieważ jest już w niej jedna System; Chodzi o to tylko, że nie ma różnicy, a to wpływa na łatwość konserwacji swojego kodu.

Interesujące jest również odnotowanie, co się stanie, jeśli Foobędzie w przestrzeni nazw Outer, a nie Outer.Inner. W takim przypadku dodanie Outer.Mathdo pliku 2 powoduje uszkodzenie pliku 1 bez względu na to, dokąd usingidzie. Oznacza to, że kompilator przeszukuje najbardziej wewnętrzną obejmującą przestrzeń nazw, zanim zajmie się jakąkolwiek usingdyrektywą.

Charlie
źródło
28
Jest to znacznie lepszy powód, aby używać instrukcji lokalnie, niż argument Marka wielu nazw przestrzeni w jednym pliku. Szczególnie sinus, kompilacja może i będzie narzekać na konflikt nazw (patrz dokumentacja StyleCop dla tej reguły (np. Opublikowana przez Jareda)).
David Schmitt
148
Przyjęta odpowiedź jest dobra, ale wydaje mi się, że to dobry powód, aby umieścić klauzule use poza obszarem nazw. Jeśli jestem w przestrzeni nazw Outer.Inner, oczekiwałbym, że użyje klasy Math z Outer.Inner, a nie System.Math.
Frank Wallis,
7
Zgadzam się z tym również. Przyjęta odpowiedź jest poprawna, ponieważ technicznie opisuje różnicę. Jednak jedna lub druga klasa będzie potrzebowała jawnego objaśnienia. Bardzo chciałbym, żeby szybkość „Math” została przetłumaczona na moją klasę lokalną, a „System.Math” odnosi się do klasy zewnętrznej - nawet jeśli System.Math był używany jako „Math” zanim istniała Outer.Math. Tak, trudniej jest naprawić wiele wcześniej istniejących referencji, ale może to być również wskazówka, że ​​może Outer.Math powinien mieć inną nazwę!
mbmcavoy
13
Świetna odpowiedź, ale wydaje mi się, że chciałbym umieścić lokalnie inne niż frameworki za pomocą instrukcji lokalnie, a ramę używać globalnych instrukcji. Czy ktoś ma dalsze wyjaśnienie, dlaczego powinienem całkowicie zmienić swoje preferencje? Również skąd to się wzięło, szablony w VS2008 umieściły poza obszarem nazw?
Tymina
31
Myślę, że jest to bardziej zła konwencja nazewnictwa niż zmiana miejsca używania. W twoim rozwiązaniu nie powinno być klasy o nazwie Math
jDeveloper
454

Wątek ten ma już kilka świetnych odpowiedzi, ale wydaje mi się, że dzięki tej dodatkowej odpowiedzi mogę przedstawić nieco więcej szczegółów.

Najpierw pamiętaj, że deklaracja przestrzeni nazw z kropkami, np .:

namespace MyCorp.TheProduct.SomeModule.Utilities
{
    ...
}

jest całkowicie równoważny z:

namespace MyCorp
{
    namespace TheProduct
    {
        namespace SomeModule
        {
            namespace Utilities
            {
                ...
            }
        }
    }
}

Jeśli chcesz, możesz zastosować usingdyrektywy na wszystkich tych poziomach. (Oczywiście chcemy mieć usingtylko w jednym miejscu, ale byłoby to zgodne z prawem w zależności od języka).

Regułę rozstrzygania, który typ jest domyślny, można luźno sformułować w następujący sposób: Najpierw wyszukaj najbardziej wewnętrzny „zakres” dopasowania, jeśli nic nie zostanie znalezione, przejdź o jeden poziom do następnego zakresu i wyszukaj tam itd. , aż do znalezienia dopasowania. Jeśli na pewnym poziomie znaleziono więcej niż jedno dopasowanie, jeśli jeden z typów pochodzi z bieżącego zestawu, wybierz go i wyślij ostrzeżenie kompilatora. W przeciwnym razie zrezygnuj (błąd czasu kompilacji).

Wyjaśnijmy teraz, co to oznacza w konkretnym przykładzie z dwoma głównymi konwencjami.

(1) Przy zastosowaniach na zewnątrz:

using System;
using System.Collections.Generic;
using System.Linq;
//using MyCorp.TheProduct;  <-- uncommenting this would change nothing
using MyCorp.TheProduct.OtherModule;
using MyCorp.TheProduct.OtherModule.Integration;
using ThirdParty;

namespace MyCorp.TheProduct.SomeModule.Utilities
{
    class C
    {
        Ambiguous a;
    }
}

W powyższym przypadku, aby dowiedzieć się, jaki Ambiguousjest typ , wyszukiwanie odbywa się w następującej kolejności:

  1. Typy zagnieżdżone w środku C(w tym dziedziczone typy zagnieżdżone)
  2. Wpisuje w bieżącej przestrzeni nazw MyCorp.TheProduct.SomeModule.Utilities
  3. Typy w przestrzeni nazw MyCorp.TheProduct.SomeModule
  4. Wpisuje w MyCorp.TheProduct
  5. Wpisuje w MyCorp
  6. Typy w pustej przestrzeni nazw (globalnej przestrzeni nazw)
  7. Rodzaje w System, System.Collections.Generic, System.Linq, MyCorp.TheProduct.OtherModule, MyCorp.TheProduct.OtherModule.Integration, iThirdParty

Druga konwencja:

(2) Przy użyciu wewnątrz:

namespace MyCorp.TheProduct.SomeModule.Utilities
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using MyCorp.TheProduct;                           // MyCorp can be left out; this using is NOT redundant
    using MyCorp.TheProduct.OtherModule;               // MyCorp.TheProduct can be left out
    using MyCorp.TheProduct.OtherModule.Integration;   // MyCorp.TheProduct can be left out
    using ThirdParty;

    class C
    {
        Ambiguous a;
    }
}

Teraz wyszukaj typ Ambiguousidzie w następującej kolejności:

  1. Typy zagnieżdżone w środku C(w tym dziedziczone typy zagnieżdżone)
  2. Wpisuje w bieżącej przestrzeni nazw MyCorp.TheProduct.SomeModule.Utilities
  3. Rodzaje w System, System.Collections.Generic, System.Linq, MyCorp.TheProduct, MyCorp.TheProduct.OtherModule, MyCorp.TheProduct.OtherModule.Integration, iThirdParty
  4. Typy w przestrzeni nazw MyCorp.TheProduct.SomeModule
  5. Wpisuje w MyCorp
  6. Typy w pustej przestrzeni nazw (globalnej przestrzeni nazw)

(Należy pamiętać, że MyCorp.TheProductbył on częścią „3.” i dlatego nie był potrzebny między „4.” a „5.”.)

Uwagi końcowe

Bez względu na to, czy umieścisz użytkowanie w deklaracji przestrzeni nazw, czy poza nią, zawsze istnieje możliwość, że ktoś później doda nowy typ o identycznej nazwie do jednej z przestrzeni nazw o wyższym priorytecie.

Ponadto, jeśli zagnieżdżona przestrzeń nazw ma taką samą nazwę jak typ, może to powodować problemy.

Przenoszenie zastosowań z jednej lokalizacji do innej zawsze jest niebezpieczne, ponieważ zmienia się hierarchia wyszukiwania i można znaleźć inny typ. Dlatego wybierz jedną konwencję i trzymaj się jej, abyś nigdy nie musiał przenosić usług.

Szablony Visual Studio domyślnie umieszczają zastosowania poza obszarem nazw (na przykład, jeśli VS wygeneruje nową klasę w nowym pliku).

Jedną (niewielką) zaletą korzystania z usług na zewnątrz jest to, że można następnie użyć dyrektyw używania dla atrybutu globalnego, na przykład [assembly: ComVisible(false)]zamiast [assembly: System.Runtime.InteropServices.ComVisible(false)].

Jeppe Stig Nielsen
źródło
46
To najlepsze wytłumaczenie, ponieważ podkreśla fakt, że pozycja instrukcji „using” jest świadomą decyzją dewelopera. W żadnym wypadku nie należy beztrosko zmieniać lokalizacji wyrażeń „używanie” bez zrozumienia implikacji. Dlatego reguła StyleCop jest po prostu głupia.
ZunTzu
194

Umieszczenie go w przestrzeniach nazw powoduje, że deklaracje są lokalne dla tej przestrzeni nazw dla pliku (w przypadku, gdy w pliku znajduje się wiele przestrzeni nazw), ale jeśli masz tylko jedną przestrzeń nazw dla pliku, to nie ma znaczenia, czy wychodzą na zewnątrz, czy w przestrzeni nazw.

using ThisNamespace.IsImported.InAllNamespaces.Here;

namespace Namespace1
{ 
   using ThisNamespace.IsImported.InNamespace1.AndNamespace2;

   namespace Namespace2
   { 
      using ThisNamespace.IsImported.InJustNamespace2;
   }       
}

namespace Namespace3
{ 
   using ThisNamespace.IsImported.InJustNamespace3;
}
Mark Cidade
źródło
przestrzenie nazw zapewniają separację logiczną, a nie fizyczną (plikową).
Jowen
9
Nie do końca jest prawdą, że nie ma różnicy; usingdyrektywy w namespaceblokach mogą odnosić się do względnych przestrzeni nazw opartych na otaczającym namespacebloku.
LUB Mapper
70
tak, wiem. ustaliliśmy, że w zaakceptowanej odpowiedzi na to pytanie pięć lat temu.
Mark Cidade
59

Według Hanselmana - Korzystanie z dyrektywy i ładowania zespołu ... i innych tego typu artykułów nie ma technicznej różnicy.

Wolę umieszczać je poza przestrzenią nazw.

Quintin Robinson
źródło
3
@Chris M: uh ... link zamieszczony w odpowiedzi wskazuje, że nie ma żadnej korzyści w porównaniu z out, faktycznie pokazuje przykład, który fałszuje roszczenia zawarte w linku, który opublikowałeś ...
Johnny
2
Tak, nie w pełni przeczytałem ten wątek, ale kupiłem go, gdy MVP stwierdzili, że miał rację. Facet go potępia, wyjaśnia i pokazuje swój kod w dół ... „Generowana przez kompilator C # IL jest taka sama w obu przypadkach. W rzeczywistości kompilator C # nie generuje dokładnie nic odpowiadającego każdej używającej dyrektywie. Korzystanie z dyrektyw jest czysto C # ism i nie mają one żadnego znaczenia dla samej platformy .NET. (Nieprawda w przypadku używania instrukcji, ale są one czymś zupełnie innym.) „ Groups.google.com/group/wpf-disciples/msg/781738deb0a15c46
Chris McKee
84
Podaj streszczenie linku. Kiedy link zostanie zerwany (bo tak się stanie, biorąc pod uwagę wystarczająco dużo czasu), nagle odpowiedź z 32 głosami uprzywilejowanymi jest warta My style is to put them outside the namespaces.- ledwie odpowiedź.
ANeves
11
Twierdzenie to jest po prostu błędne ... istnieje różnica techniczna, a twój własny cytat tak mówi ... w rzeczywistości o to właśnie chodzi. Usuń tę błędną odpowiedź ... są o wiele lepsze i dokładne.
Jim Balter
53

Zgodnie z dokumentacją StyleCop:

SA1200: UsingDirectivesMustBePlacedWithinNamespace

Przyczyna AC # za pomocą dyrektywy jest umieszczony poza elementem przestrzeni nazw.

Opis reguły Naruszenie tej reguły występuje, gdy dyrektywa using lub dyrektywa using-alias zostanie umieszczona poza elementem przestrzeni nazw, chyba że plik nie zawiera żadnych elementów przestrzeni nazw.

Na przykład poniższy kod spowodowałby dwa naruszenia tej reguły.

using System;
using Guid = System.Guid;

namespace Microsoft.Sample
{
    public class Program
    {
    }
}

Poniższy kod nie spowoduje jednak naruszenia tej reguły:

namespace Microsoft.Sample
{
    using System;
    using Guid = System.Guid;

    public class Program
    {
    }
}

Ten kod skompiluje się czysto, bez żadnych błędów kompilatora. Nie jest jednak jasne, która wersja typu Guid jest przydzielana. Jeśli dyrektywa using zostanie przeniesiona do przestrzeni nazw, jak pokazano poniżej, wystąpi błąd kompilatora:

namespace Microsoft.Sample
{
    using Guid = System.Guid;
    public class Guid
    {
        public Guid(string s)
        {
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Guid g = new Guid("hello");
        }
    }
}

Kod kończy się niepowodzeniem w przypadku następującego błędu kompilatora, znalezionego w wierszu zawierającym Guid g = new Guid("hello");

CS0576: Przestrzeń nazw „Microsoft.Sample” zawiera definicję sprzeczną z aliasem „Guid”

Kod tworzy alias typu System.Guid o nazwie Guid, a także tworzy własny typ o nazwie Guid z pasującym interfejsem konstruktora. Później kod tworzy instancję typu Guid. Aby utworzyć to wystąpienie, kompilator musi wybrać jedną z dwóch różnych definicji Guid. Kiedy dyrektywa using-alias zostanie umieszczona poza elementem przestrzeni nazw, kompilator wybierze lokalną definicję Guid zdefiniowaną w lokalnej przestrzeni nazw i całkowicie zignoruje dyrektywę using-alias zdefiniowaną poza przestrzenią nazw. To niestety nie jest oczywiste podczas czytania kodu.

Gdy dyrektywa using-alias znajduje się w obszarze nazw, kompilator musi jednak wybierać między dwoma różnymi, sprzecznymi typami Guid, które są zdefiniowane w tej samej przestrzeni nazw. Oba te typy zapewniają zgodnego konstruktora. Kompilator nie może podjąć decyzji, więc oznacza błąd kompilatora.

Umieszczenie dyrektywy using-alias poza przestrzenią nazw jest złą praktyką, ponieważ może prowadzić do nieporozumień w sytuacjach takich jak ta, gdzie nie jest oczywiste, która wersja tego typu jest faktycznie używana. Może to potencjalnie prowadzić do błędu, który może być trudny do zdiagnozowania.

Umieszczenie dyrektyw przy użyciu aliasu w elemencie przestrzeni nazw eliminuje to jako źródło błędów.

  1. Wiele przestrzeni nazw

Umieszczanie wielu elementów przestrzeni nazw w jednym pliku jest na ogół złym pomysłem, ale jeśli i kiedy to zostanie zrobione, dobrym pomysłem jest umieszczenie wszystkich za pomocą dyrektyw w obrębie każdego z elementów przestrzeni nazw, a nie globalnie na górze pliku. Spowoduje to ścisłe zawężenie przestrzeni nazw, a także pomoże uniknąć opisanych powyżej zachowań.

Należy zauważyć, że kiedy kod został napisany przy użyciu dyrektyw umieszczonych poza przestrzenią nazw, należy zachować ostrożność podczas przenoszenia tych dyrektyw w przestrzeni nazw, aby upewnić się, że nie zmienia to semantyki kodu. Jak wyjaśniono powyżej, umieszczenie dyrektyw przy użyciu aliasu w elemencie przestrzeni nazw umożliwia kompilatorowi wybór między konfliktami typów w sposób, który nie nastąpi, gdy dyrektywy zostaną umieszczone poza przestrzenią nazw.

Jak naprawić naruszenia Aby naprawić naruszenie tej reguły, przenieś wszystkie za pomocą dyrektyw i dyrektyw przy użyciu aliasu w elemencie przestrzeni nazw.

JaredCacurak
źródło
1
@Jared - jak zauważyłem w mojej odpowiedzi, moim preferowanym obejściem / rozwiązaniem jest posiadanie tylko jednej klasy na plik. Myślę, że jest to dość powszechna konwencja.
benPearce
24
Rzeczywiście, jest to również reguła StyleCop! SA1402: Dokument AC # może zawierać tylko jedną klasę na poziomie głównym, chyba że wszystkie klasy są częściowe i są tego samego typu. Pokazywanie jednej reguły przez łamanie innej po prostu kapie złym sosem.
Zadanie
6
Wybitny za to, że jest pierwszą odpowiedzią, która rzeczywiście obejmuje go z perspektywy StyleCop. Osobiście podoba mi się wygląd usingpoza przestrzenią nazw. Wewnętrzna usings wygląda tak brzydki do mnie. :)
nawfal
2
Wreszcie dobra odpowiedź na pytanie. Komentarz BenPearce jest nieistotny ... nie ma to nic wspólnego z liczbą klas w pliku.
Jim Balter
35

Występuje problem z umieszczaniem instrukcji przy użyciu w przestrzeni nazw, gdy chcesz używać aliasów. Alias ​​nie korzysta z wcześniejszych usinginstrukcji i musi być w pełni kwalifikowany.

Rozważać:

namespace MyNamespace
{
    using System;
    using MyAlias = System.DateTime;

    class MyClass
    {
    }
}

przeciw:

using System;

namespace MyNamespace
{
    using MyAlias = DateTime;

    class MyClass
    {
    }
}

Może to być szczególnie wyraźne, jeśli masz długi alias, taki jak następujący (tak znalazłem problem):

using MyAlias = Tuple<Expression<Func<DateTime, object>>, Expression<Func<TimeSpan, object>>>;

Dzięki usinginstrukcjom w przestrzeni nazw nagle staje się:

using MyAlias = System.Tuple<System.Linq.Expressions.Expression<System.Func<System.DateTime, object>>, System.Linq.Expressions.Expression<System.Func<System.TimeSpan, object>>>;

Nie ładna

Neo
źródło
1
Twoje classpotrzeby nazwę (identyfikator). Nie możesz miećusing dyrektywy wewnątrz klasy, jak to wskazujesz. Musi znajdować się na poziomie przestrzeni nazw, na przykład na zewnątrz namespacelub na zewnątrz namespace(ale nie wewnątrz klasy / interfejsu / itp.).
Jeppe Stig Nielsen
@JeppeStigNielsen Thanks. Źle wprowadziłem usingdyrektywy. Zredagowałem to tak, jak zamierzałem. Dzięki za wskazanie. Rozumowanie jest jednak nadal takie samo.
Neo
4

Jak powiedział Jeppe Stig Nielsen , ten wątek ma już świetne odpowiedzi, ale myślałem, że o tej dość oczywistej subtelności warto też wspomnieć.

using dyrektywy określone w przestrzeniach nazw mogą tworzyć krótszy kod, ponieważ nie muszą być w pełni kwalifikowane, jak wtedy, gdy są określone na zewnątrz.

Poniższy przykład działa, ponieważ wszystkie typy Fooi Barto zarówno w tej samej przestrzeni nazw globalnej Outer.

Załóżmy plik kodu Foo.cs :

namespace Outer.Inner
{
    class Foo { }
}

I Bar.cs :

namespace Outer
{
    using Outer.Inner;

    class Bar
    {
        public Foo foo;
    }
}

W usingskrócie może to pomijać zewnętrzną przestrzeń nazw w dyrektywie:

namespace Outer
{
    using Inner;

    class Bar
    {
        public Foo foo;
    }
}
Biszkopty
źródło
8
To prawda, że ​​„możesz pominąć zewnętrzną przestrzeń nazw”, ale to nie znaczy, że powinieneś. Dla mnie jest to kolejny argument, dlaczego stosowanie dyrektyw (innych niż aliasy jak w odpowiedzi @ Neo) powinno wykraczać poza przestrzeń nazw, aby wymusić w pełni kwalifikowane nazwy przestrzeni nazw.
Keith Robertson,
4

Jedna zmarszczka, na którą natknąłem się (która nie jest uwzględniona w innych odpowiedziach):

Załóżmy, że masz te przestrzenie nazw:

  • Coś innego
  • Parent.Something.Inne

Kiedy używasz using Something.Other poza a namespace Parent, odnosi się do pierwszego (Coś. Inne).

Jeśli jednak użyjesz go w deklaracji przestrzeni nazw, odnosi się do drugiej (Parent.Something.Other)!

Istnieje proste rozwiązanie: dodaj global::przedrostek „ ”: docs

namespace Parent
{
   using global::Something.Other;
   // etc
}
Hans Keinging
źródło
2

Przyczyny techniczne są omówione w odpowiedziach i myślę, że w końcu chodzi o osobiste preferencje, ponieważ różnica nie jest tak duża, a obie są kompromisy. Domyślny szablon programu Visual Studio do tworzenia .csplików korzysta z usingdyrektyw poza obszarami nazw, np

Można dostosować stylecop, aby sprawdzać usingdyrektywy poza obszarami nazw, dodając stylecop.jsonplik do katalogu głównego pliku projektu w następujący sposób:

{
  "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
    "orderingRules": {
      "usingDirectivesPlacement": "outsideNamespace"
    }
  }
}

Możesz utworzyć ten plik konfiguracyjny na poziomie rozwiązania i dodać go do swoich projektów jako „Istniejący plik linku”, aby udostępnić konfigurację również we wszystkich swoich projektach.

sotn
źródło
2

Inna subtelność, która nie wydaje mi się, że została ujęta w innych odpowiedziach, dotyczy sytuacji, gdy masz klasę i przestrzeń nazw o tej samej nazwie.

Kiedy importujesz w przestrzeni nazw, znajdzie klasę. Jeśli import znajduje się poza obszarem nazw, wówczas import zostanie zignorowany, a klasa i przestrzeń nazw muszą być w pełni kwalifikowane.

//file1.cs
namespace Foo
{
    class Foo
    {
    }
}

//file2.cs
namespace ConsoleApp3
{
    using Foo;
    class Program
    {
        static void Main(string[] args)
        {
            //This will allow you to use the class
            Foo test = new Foo();
        }
    }
}

//file2.cs
using Foo; //Unused and redundant    
namespace Bar
{
    class Bar
    {
        Bar()
        {
            Foo.Foo test = new Foo.Foo();
            Foo test = new Foo(); //will give you an error that a namespace is being used like a class.
        }
    }
}
Ben Gardner
źródło
-8

Lepszą praktyką jest, aby te domyślne, które używają np. „ Referencji ” używanych w rozwiązaniu źródłowym, znajdowały się poza przestrzeniami nazw, a te, które są „nowymi dodanymi referencjami”, są dobrą praktyką, należy umieszczać je w przestrzeni nazw. Ma to na celu rozróżnienie, jakie odniesienia są dodawane.

Israel Ocbina
źródło
6
Nie, właściwie to zły pomysł. Nie należy opierać lokalizacji między lokalnymi i globalnymi zakresami stosowania dyrektyw na tym, że są one nowo dodawane, czy nie. Zamiast tego dobrą praktyką jest ich alfabetyczne, z wyjątkiem odniesień BCL, które powinny znaleźć się na górze.
Abel