Sollten 'using'-Direktiven innerhalb oder außerhalb des Namespace liegen?

2060

Ich habe StyleCop über einen C # -Code ausgeführt und es wird immer wieder gemeldet, dass sich meine usingAnweisungen im Namespace befinden sollten.

Gibt es einen technischen Grund, die usingDirektiven innerhalb und nicht außerhalb des Namespace zu platzieren?

benPearce
quelle
4
Manchmal macht es einen Unterschied, wo Sie Verwendungen platzieren: stackoverflow.com/questions/292535/linq-to-sql-designer-bug
gius
82
Nur als Referenz gibt es Implikationen, die über die Frage nach mehreren Klassen pro Datei hinausgehen. Wenn Sie mit dieser Frage noch nicht vertraut sind, lesen Sie bitte weiter.
Charlie
3
@ user-12506 - Dies funktioniert nicht sehr gut in einem mittleren bis großen Entwicklungsteam, in dem ein gewisses Maß an Codekonsistenz erforderlich ist. Und wie bereits erwähnt, finden Sie möglicherweise Randfälle, die nicht wie erwartet funktionieren, wenn Sie die verschiedenen Layouts nicht verstehen.
BenPearce
34
Terminologie: Dies sind keine using Aussagen ; Sie sind using Richtlinien . Eine usingAnweisung ist andererseits eine Sprachstruktur, die zusammen mit anderen Anweisungen innerhalb eines Methodenkörpers usw. auftritt. Als Beispiel using (var e = s.GetEnumerator()) { /* ... */ }gilt eine Anweisung, die lose mit der identisch ist var e = s.GetEnumerator(); try { /* ... */ } finally { if (e != null) { e.Dispose(); } }.
Jeppe Stig Nielsen
1
Wenn dies noch nicht von irgendjemandem erwähnt wurde, empfiehlt auch Microsoft, usingAnweisungen in die namespaceDeklarationen in ihren internen Codierungsrichtlinien aufzunehmen
user1451111

Antworten:

2133

Es gibt tatsächlich einen (subtilen) Unterschied zwischen den beiden. Stellen Sie sich vor, Sie haben den folgenden Code in File1.cs:

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

Stellen Sie sich nun vor, jemand fügt dem Projekt eine weitere Datei (File2.cs) hinzu, die folgendermaßen aussieht:

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

Der Compiler sucht, Outerbevor er diese usingAnweisungen außerhalb des Namespace betrachtet, und findet Outer.Mathstattdessen statt System.Math. Leider (oder vielleicht zum Glück?) Hat Outer.Mathkein PIMitglied, so dass File1 jetzt kaputt ist.

Dies ändert sich, wenn Sie die usingNamespace-Deklaration wie folgt einfügen:

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

Jetzt sucht der Compiler Systemvor dem Suchen Outer, findet System.Mathund alles ist gut.

Einige würden argumentieren, dass Mathdies ein schlechter Name für eine benutzerdefinierte Klasse sein könnte, da bereits eine vorhanden ist System. Der Punkt hier ist nur , dass es ist ein Unterschied, und es wirkt sich auf die Wartbarkeit des Codes.

Es ist auch interessant festzustellen, was passiert, wenn Fooes sich im Namespace Outerbefindet und nicht Outer.Inner. In diesem Fall wird durch Hinzufügen Outer.Mathvon Datei2 Datei1 unterbrochen, unabhängig davon, wohin das usinggeht. Dies bedeutet, dass der Compiler den innersten umschließenden Namespace durchsucht, bevor er eine usingDirektive betrachtet.

Charlie
quelle
28
Dies ist imho ein viel besserer Grund, Anweisungen lokal zu verwenden als Marks Argument mit mehreren Namespaces in einer Datei. Insbesondere kann und wird sich die Kompilierung über den Namenskonflikt beschweren (siehe die StyleCop-Dokumentation zu dieser Regel (z. B. wie von Jared veröffentlicht)).
David Schmitt
148
Die akzeptierte Antwort ist gut, aber für mich scheint es ein guter Grund zu sein, die using-Klauseln außerhalb des Namespace zu platzieren. Wenn ich mich im Namespace Outer.Inner befinde, würde ich erwarten, dass die Math-Klasse von Outer.Inner und nicht System.Math verwendet wird.
Frank Wallis
7
Dem stimme ich auch zu. Die akzeptierte Antwort ist insofern richtig, als sie den Unterschied technisch beschreibt. Die eine oder andere Klasse benötigt jedoch ein explizites Callout. Ich würde sehr wahrscheinlich "Math" in meine eigene lokale Klasse auflösen lassen, und "System.Math" bezieht sich auf die externe Klasse - selbst wenn System.Math als "Math" verwendet wurde, bevor Outer.Math existierte. Ja, es ist mehr Arbeit, jedoch viele bereits vorhandene Referenzen zu reparieren, aber das könnte auch ein Hinweis darauf sein, dass Outer.Math möglicherweise einen anderen Namen haben sollte!
mbmcavoy
13
Tolle Antwort, aber es scheint mir, dass ich nur Nicht-Framework-Anweisungen lokal verwenden und das Framework mithilfe von Anweisungen global halten möchte. Hat jemand weitere Erklärungen, warum ich meine Präferenz komplett ändern sollte? Auch woher kam dies, die Vorlagen in VS2008 außerhalb des Namespace verwendet?
Thymin
31
Ich denke, dies ist eher eine schlechte Namenskonvention, als den Ort Ihrer Verwendung zu ändern. Es sollte keine Klasse namens Mathe in Ihrer Lösung geben
jDeveloper
454

Dieser Thread hat bereits einige großartige Antworten, aber ich denke, ich kann mit dieser zusätzlichen Antwort ein wenig mehr Details bringen.

Denken Sie zunächst daran, dass eine Namespace-Deklaration mit Punkten wie:

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

ist völlig gleichbedeutend mit:

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

Wenn Sie möchten, können Sie usingauf all diesen Ebenen Richtlinien festlegen. (Natürlich möchten wir usings nur an einem Ort haben, aber es wäre je nach Sprache legal.)

Die Regel zum Auflösen des implizierten Typs kann lose wie folgt angegeben werden: Durchsuchen Sie zuerst den innersten "Bereich" nach einer Übereinstimmung. Wenn dort nichts gefunden wird, gehen Sie eine Ebene zum nächsten Bereich und suchen Sie dort und so weiter . bis eine Übereinstimmung gefunden wird. Wenn auf einer bestimmten Ebene mehr als eine Übereinstimmung gefunden wird und einer der Typen aus der aktuellen Assembly stammt, wählen Sie diesen aus und geben Sie eine Compiler-Warnung aus. Andernfalls geben Sie auf (Fehler beim Kompilieren).

Lassen Sie uns nun in einem konkreten Beispiel mit den beiden Hauptkonventionen explizit erläutern, was dies bedeutet.

(1) Bei Verwendung außerhalb:

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;
    }
}

Im obigen Fall Ambiguouserfolgt die Suche in der folgenden Reihenfolge , um herauszufinden, um welchen Typ es sich handelt:

  1. Verschachtelte Typen im Inneren C(einschließlich geerbter verschachtelter Typen)
  2. Typen im aktuellen Namespace MyCorp.TheProduct.SomeModule.Utilities
  3. Typen im Namespace MyCorp.TheProduct.SomeModule
  4. Tippt ein MyCorp.TheProduct
  5. Tippt ein MyCorp
  6. Typen im Null- Namespace (dem globalen Namespace)
  7. Arten in System, System.Collections.Generic, System.Linq, MyCorp.TheProduct.OtherModule, MyCorp.TheProduct.OtherModule.Integration, undThirdParty

Die andere Konvention:

(2) Mit Verwendungen im Inneren:

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;
    }
}

Die Suche nach dem Typ erfolgt nun Ambiguousin dieser Reihenfolge:

  1. Verschachtelte Typen im Inneren C(einschließlich geerbter verschachtelter Typen)
  2. Typen im aktuellen Namespace MyCorp.TheProduct.SomeModule.Utilities
  3. Arten in System, System.Collections.Generic, System.Linq, MyCorp.TheProduct, MyCorp.TheProduct.OtherModule, MyCorp.TheProduct.OtherModule.Integration, undThirdParty
  4. Typen im Namespace MyCorp.TheProduct.SomeModule
  5. Tippt ein MyCorp
  6. Typen im Null- Namespace (dem globalen Namespace)

(Beachten Sie, dass dies MyCorp.TheProductTeil von "3." war und daher zwischen "4." und "5." nicht benötigt wurde.)

Abschließende Bemerkungen

Unabhängig davon, ob Sie die Verwendungen innerhalb oder außerhalb der Namespace-Deklaration platzieren, besteht immer die Möglichkeit, dass jemand später einem der Namespaces mit höherer Priorität einen neuen Typ mit identischem Namen hinzufügt.

Wenn ein verschachtelter Namespace denselben Namen wie ein Typ hat, kann dies zu Problemen führen.

Es ist immer gefährlich, die Verwendungen von einem Ort an einen anderen zu verschieben, da sich die Suchhierarchie ändert und möglicherweise ein anderer Typ gefunden wird. Wählen Sie daher eine Konvention und halten Sie sich daran, damit Sie die Verwendung nie verschieben müssen.

In den Vorlagen von Visual Studio werden die Verwendungen standardmäßig außerhalb des Namespace platziert (z. B. wenn VS eine neue Klasse in einer neuen Datei generiert).

Ein (kleiner) Vorteil von usings mit außen ist , dass Sie können dann die Verwendung von Richtlinien für ein globales Attribut nutzen, zum Beispiel [assembly: ComVisible(false)]statt [assembly: System.Runtime.InteropServices.ComVisible(false)].

Jeppe Stig Nielsen
quelle
46
Dies ist die beste Erklärung, da sie die Tatsache hervorhebt, dass die Position der "using" -Anweisungen eine bewusste Entscheidung des Entwicklers ist. In keinem Fall sollte jemand den Ort der "using" -Anweisungen unachtsam ändern, ohne die Auswirkungen zu verstehen. Daher ist die StyleCop-Regel einfach nur dumm.
ZunTzu
194

Wenn Sie es in die Namespaces einfügen, werden die Deklarationen lokal für diesen Namespace für die Datei (falls Sie mehrere Namespaces in der Datei haben). Wenn Sie jedoch nur einen Namespace pro Datei haben, spielt es keine große Rolle, ob sie nach draußen oder nach außen gehen innerhalb des Namespace.

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
quelle
Namespaces bieten eine logische Trennung, keine physische (Datei-).
Jowen
9
Es ist nicht ganz richtig, dass es keinen Unterschied gibt; usingDirektiven innerhalb von namespaceBlöcken können sich auf relative Namespaces beziehen, die auf dem umschließenden namespaceBlock basieren .
ODER Mapper
70
ja ich weiß. Wir haben festgestellt, dass diese Frage vor fünf Jahren akzeptiert wurde.
Mark Cidade
59

Laut Hanselman - Verwenden von Richtlinie und Laden von Baugruppen ... und anderen derartigen Artikeln gibt es technisch keinen Unterschied.

Ich bevorzuge es, sie außerhalb von Namespaces zu platzieren.

Quintin Robinson
quelle
3
@ Chris M: äh ... der in der Antwort gepostete Link zeigt an, dass es keinen Vorteil für In vs. Out gibt. Er zeigt tatsächlich ein Beispiel, das die Behauptung in dem von Ihnen geposteten Link verfälscht ...
Johnny
2
Ja, ich habe den Thread nicht vollständig gelesen, mich aber eingekauft, als die MVPs sagten, dass er richtig war. Ein Typ widerlegt es, erklärt es und zeigt seinen Code weiter unten ... "Die IL, die der C # -Compiler generiert, ist in beiden Fällen dieselbe. Tatsächlich generiert der C # -Compiler genau nichts, was jeder Verwendung der Direktive entspricht. Die Verwendung von Direktiven ist rein a C # ism, und sie haben keine Bedeutung für .NET selbst. (Nicht wahr für die Verwendung von Anweisungen, aber diese sind etwas ganz anderes.) " Groups.google.com/group/wpf-disciples/msg/781738deb0a15c46
Chris McKee
84
Bitte fügen Sie eine Zusammenfassung des Links bei. Wenn die Verbindung unterbrochen wird (weil es wird geschehen, genug Zeit gegeben), plötzlich eine Antwort mit 32 upvotes nur wert ist My style is to put them outside the namespaces.- kaum eine Antwort überhaupt.
Aneves
11
Die Behauptung hier ist einfach falsch ... es gibt einen technischen Unterschied und Ihr eigenes Zitat sagt es ... tatsächlich geht es darum. Bitte löschen Sie diese falsche Antwort ... es gibt weitaus bessere und genauere.
Jim Balter
53

Laut StyleCop-Dokumentation:

SA1200: UsingDirectivesMustBePlacedWithinNamespace

Ursache AC # mit der Direktive wird außerhalb eines Namespace-Elements platziert.

Regelbeschreibung Ein Verstoß gegen diese Regel tritt auf, wenn eine using-Direktive oder eine using-Alias-Direktive außerhalb eines Namespace-Elements platziert wird, es sei denn, die Datei enthält keine Namespace-Elemente.

Der folgende Code würde beispielsweise zu zwei Verstößen gegen diese Regel führen.

using System;
using Guid = System.Guid;

namespace Microsoft.Sample
{
    public class Program
    {
    }
}

Der folgende Code würde jedoch nicht zu Verstößen gegen diese Regel führen:

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

    public class Program
    {
    }
}

Dieser Code wird ohne Compilerfehler sauber kompiliert. Es ist jedoch unklar, welche Version des Guid-Typs zugewiesen wird. Wenn die using-Direktive wie unten gezeigt in den Namespace verschoben wird, tritt ein Compilerfehler auf:

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");
        }
    }
}

Der Code schlägt bei dem folgenden Compilerfehler fehl, der in der Zeile mit gefunden wird Guid g = new Guid("hello");

CS0576: Der Namespace 'Microsoft.Sample' enthält eine Definition, die mit dem Alias ​​'Guid' in Konflikt steht.

Der Code erstellt einen Alias ​​für den System.Guid-Typ namens Guid und einen eigenen Typ namens Guid mit einer passenden Konstruktorschnittstelle. Später erstellt der Code eine Instanz vom Typ Guid. Um diese Instanz zu erstellen, muss der Compiler zwischen den beiden unterschiedlichen Definitionen von Guid wählen. Wenn die using-Alias-Direktive außerhalb des Namespace-Elements platziert wird, wählt der Compiler die lokale Definition von Guid aus, die im lokalen Namespace definiert ist, und ignoriert die using-Alias-Direktive, die außerhalb des Namespace definiert ist, vollständig. Dies ist beim Lesen des Codes leider nicht ersichtlich.

Wenn die using-Alias-Direktive jedoch im Namespace positioniert ist, muss der Compiler zwischen zwei verschiedenen, widersprüchlichen Guid-Typen wählen, die beide im selben Namespace definiert sind. Beide Typen bieten einen passenden Konstruktor. Der Compiler kann keine Entscheidung treffen und kennzeichnet daher den Compilerfehler.

Das Platzieren der using-alias-Direktive außerhalb des Namespace ist eine schlechte Praxis, da dies in Situationen wie dieser zu Verwirrung führen kann, in denen nicht klar ist, welche Version des Typs tatsächlich verwendet wird. Dies kann möglicherweise zu einem Fehler führen, der möglicherweise schwer zu diagnostizieren ist.

Durch das Platzieren von using-alias-Direktiven im Namespace-Element wird dies als Fehlerquelle beseitigt.

  1. Mehrere Namespaces

Das Platzieren mehrerer Namespace-Elemente in einer einzelnen Datei ist im Allgemeinen eine schlechte Idee. In diesem Fall empfiehlt es sich jedoch, alle verwendeten Direktiven in jedem der Namespace-Elemente zu platzieren und nicht global am Anfang der Datei. Dies wird die Namespaces eng umrahmen und auch dazu beitragen, das oben beschriebene Verhalten zu vermeiden.

Es ist wichtig zu beachten, dass beim Schreiben von Code unter Verwendung von Anweisungen außerhalb des Namespace beim Verschieben dieser Anweisungen innerhalb des Namespace darauf geachtet werden sollte, dass dadurch die Semantik des Codes nicht geändert wird. Wie oben erläutert, kann der Compiler beim Platzieren von Direktiven mit Alias ​​innerhalb des Namespace-Elements zwischen widersprüchlichen Typen auf eine Weise wählen, die nicht auftritt, wenn die Direktiven außerhalb des Namespace platziert werden.

So beheben Sie Verstöße Um einen Verstoß gegen diese Regel zu beheben, verschieben Sie alle Direktiven und Alias-Direktiven innerhalb des Namespace-Elements.

JaredCacurak
quelle
1
@Jared - Wie ich in meiner Antwort festgestellt habe, besteht meine bevorzugte Problemumgehung / Lösung darin, immer nur eine Klasse pro Datei zu haben. Ich denke, dass dies eine ziemlich verbreitete Konvention ist.
BenPearce
24
In der Tat ist es auch eine StyleCop-Regel! SA1402: Das AC # -Dokument darf nur eine einzige Klasse auf Stammebene enthalten, es sei denn, alle Klassen sind partiell und vom gleichen Typ. Das Zeigen einer Regel durch Brechen einer anderen tropft nur mit falscher Sauce.
Aufgabe
6
Upvoted als erste Antwort, die es tatsächlich aus der StyleCop-Perspektive abdeckt. Persönlich mag ich das visuelle Gefühl von usings außerhalb des Namespace. Inneres usingsieht für mich so hässlich aus. :)
Nawfal
2
Endlich eine gute Antwort auf die Frage. Und der Kommentar von benPearce ist irrelevant ... das hat nichts mit der Anzahl der Klassen in der Datei zu tun.
Jim Balter
35

Es gibt ein Problem beim Platzieren von using-Anweisungen im Namespace, wenn Sie Aliase verwenden möchten. Der Alias ​​profitiert nicht von den früheren usingAnweisungen und muss vollständig qualifiziert sein.

Erwägen:

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

    class MyClass
    {
    }
}

gegen:

using System;

namespace MyNamespace
{
    using MyAlias = DateTime;

    class MyClass
    {
    }
}

Dies kann besonders ausgeprägt sein, wenn Sie einen langwierigen Alias ​​wie den folgenden haben (so habe ich das Problem gefunden):

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

Mit usingAnweisungen im Namespace wird es plötzlich:

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

Nicht hübsch.

Neo
quelle
1
Sie classbenötigen einen Namen (Kennung). Sie können keine usingDirektive innerhalb einer Klasse haben, wie Sie angeben. Es muss sich auf einer Namespace-Ebene befinden, z. B. außerhalb der äußersten namespaceoder nur innerhalb der innersten Ebene namespace(jedoch nicht innerhalb einer Klasse / Schnittstelle / etc.)
Jeppe Stig Nielsen
@ JeppeStigNielsen Danke. Ich habe die usingAnweisungen fälschlicherweise falsch platziert. Ich habe es so bearbeitet, wie ich es beabsichtigt hatte. Vielen Dank für den Hinweis. Die Argumentation ist jedoch immer noch dieselbe.
Neo
4

Wie Jeppe Stig Nielsen sagte , hat dieser Thread bereits großartige Antworten, aber ich dachte, dass diese ziemlich offensichtliche Subtilität auch erwähnenswert ist.

using Anweisungen, die in Namespaces angegeben werden, können zu kürzerem Code führen, da sie nicht vollständig qualifiziert sein müssen, wie wenn sie außen angegeben werden.

Das folgende Beispiel funktioniert, da sich die Typen Foound Barbeide im selben globalen Namespace befinden Outer.

Angenommen, die Codedatei Foo.cs :

namespace Outer.Inner
{
    class Foo { }
}

Und Bar.cs :

namespace Outer
{
    using Outer.Inner;

    class Bar
    {
        public Foo foo;
    }
}

Das kann den äußeren Namespace in der usingDirektive weglassen , kurz:

namespace Outer
{
    using Inner;

    class Bar
    {
        public Foo foo;
    }
}
Kekse
quelle
8
Es ist wahr, dass Sie "den äußeren Namespace weglassen können", aber das bedeutet nicht, dass Sie es sollten. Für mich ist dies ein weiteres Argument dafür, warum die Verwendung von Direktiven (außer Aliasnamen wie in der Antwort von @ Neo) außerhalb des Namespace liegen sollte, um vollständig qualifizierte Namespace-Namen zu erzwingen.
Keith Robertson
4

Eine Falte, auf die ich gestoßen bin (die in anderen Antworten nicht behandelt wird):

Angenommen, Sie haben folgende Namespaces:

  • Etwas anderes
  • Parent.Something.Other

Wenn Sie using Something.Other außerhalb von a verwenden namespace Parent, bezieht es sich auf das erste (Something.Other).

Wenn Sie es jedoch innerhalb dieser Namespace-Deklaration verwenden, bezieht es sich auf die zweite (Parent.Something.Other)!

Es gibt eine einfache Lösung: Fügen Sie das global::Präfix " " hinzu: docs

namespace Parent
{
   using global::Something.Other;
   // etc
}
Hans Keing
quelle
2

Die technischen Gründe werden in den Antworten diskutiert und ich denke, dass es am Ende um die persönlichen Vorlieben geht, da der Unterschied nicht so groß ist und es für beide Kompromisse gibt. Die Standardvorlage von Visual Studio zum Erstellen von .csDateien verwendet usingAnweisungen außerhalb von Namespaces, z

Sie können stylecop anpassen, um usingAnweisungen außerhalb von Namespaces zu überprüfen, indem Sie eine stylecop.jsonDatei im Stammverzeichnis der Projektdatei wie folgt hinzufügen :

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

Sie können diese Konfigurationsdatei auf Lösungsebene erstellen und als "Vorhandene Linkdatei" zu Ihren Projekten hinzufügen, um die Konfiguration auch für alle Ihre Projekte freizugeben.

sotn
quelle
2

Eine andere Subtilität, von der ich nicht glaube, dass sie von den anderen Antworten abgedeckt wurde, ist, wenn Sie eine Klasse und einen Namespace mit demselben Namen haben.

Wenn Sie den Import im Namespace haben, wird die Klasse gefunden. Wenn sich der Import außerhalb des Namespace befindet, wird der Import ignoriert und die Klasse und der Namespace müssen vollständig qualifiziert sein.

//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
quelle
-8

Es ist eine bessere Vorgehensweise, wenn diejenigen, die standardmäßig " Referenzen " verwenden, die in Ihrer Quelllösung verwendet werden, außerhalb der Namespaces liegen sollten und diejenigen, die "neu hinzugefügte Referenzen" sind, eine gute Vorgehensweise sind, wenn Sie sie in den Namespace einfügen. Hiermit wird unterschieden, welche Referenzen hinzugefügt werden.

Israel Ocbina
quelle
6
Nein, eigentlich ist das eine schlechte Idee. Sie sollten den Speicherort zwischen lokalem und globalem Gültigkeitsbereich für die Verwendung von Direktiven nicht auf der Tatsache basieren, dass sie neu hinzugefügt wurden oder nicht. Stattdessen empfiehlt es sich, sie zu alphabetisieren, mit Ausnahme von BCL-Referenzen, die oben stehen sollten.
Abel