2013-09-11 20 views
51

Ich organisiere ein Bibliotheksprojekt und ich habe eine zentrale Manager-Klasse namens Scenegraph und eine ganze Reihe anderer Klassen, die im Scenegraph-Namensraum leben.Namespace und Klasse mit dem gleichen Namen?

Was ich wirklich mag, ist für die Scenegraph MyLib.Scenegraph und die anderen Klassen MyLib.Scenegraph.* sein zu sein, aber es scheint die einzige Möglichkeit, das zu tun wäre, alle anderen Klassen inneren Klassen von Scenegraph im Szenengraph zu machen. CS-Datei und das ist einfach zu unhandlich.

Stattdessen habe ich es als Mylib.Scenegraph.Scenegraph und MyLib.Scenegraph.* organisiert, die Art von funktioniert, aber ich finde, dass Visual Studio unter einigen Bedingungen verwirrt wird, ob ich auf die Klasse oder den Namespace verweise.

Gibt es eine gute Möglichkeit, dieses Paket so zu organisieren, dass es für Benutzer bequem ist, ohne all meinen Code in einer unüberwindlichen Unordnung zusammenzufassen?

Antwort

64

Ich empfehle nicht, eine Klasse wie ihren Namensraum zu benennen, siehe this.

The Framework Design Guidelines say in section 3.4 “do not use the same name for a namespace and a type in that namespace”. That is:

namespace MyContainers.List 
{ 
    public class List { … } 
} 

Why is this badness? Oh, let me count the ways.

You can get yourself into situations where you think you are referring to one thing but in fact are referring to something else. Suppose you end up in this unfortunate situation: you are writing Blah.DLL and importing Foo.DLL and Bar.DLL, which, unfortunately, both have a type called Foo:

// Foo.DLL: 
namespace Foo { public class Foo { } } 

// Bar.DLL: 
namespace Bar { public class Foo { } } 

// Blah.DLL: 
namespace Blah 
{ 
using Foo; 
using Bar; 
class C { Foo foo; } 
} 

The compiler gives an error. “Foo” is ambiguous between Foo.Foo and Bar.Foo. Bummer. I guess I’ll fix that by fully qualifying the name:

class C { Foo.Foo foo; } 

This now gives the ambiguity error “Foo in Foo.Foo is ambiguous between Foo.Foo and Bar.Foo”. We still don’t know what the first Foo refers to, and until we can figure that out, we don’t even bother to try to figure out what the second one refers to.

+3

Es ist ein interessanter Punkt. Ich beobachte es immer noch. Vielen Dank. Ich muss ehrlich Argumente sein, die mit "Der Stilführer sagt" beginnen, beeindrucken mich nicht. Ich habe eine Menge ungerechtfertigten Mist in Style Guides gesehen. Aber Sie machen eine gute praktische Argumentation oben. Überlegenswert, wie auch immer. – user430788

+0

Danke, dass du das erklärst ... Ich war kurz davor bei .NET sauer zu werden, bis du einen vollkommen guten Grund erklärt hast, dass es so funktioniert. – levininja

+3

Die Antwort sagt "was nicht zu tun". Während einige der Stack-Benutzer nach "Was zu tun" suchen. Würde jemand Ant_222 empfehlen, zu antworten? – fantastory

3

CA1724: Type Names Should Not Match Namespaces ...

Grundsätzlich, wenn Sie Code-Analyse folgen für die richtige Codierung diese Regel sagt nicht wha zu tun Das versuchst du zu tun. Code-Analyse ist sehr nützlich hilft Ihnen bei der Suche Potenzial Probleme.

4

Ich würde vorschlagen, dass Sie dem Ratschlag folgen, den ich auf microsoft.public.dotnet.languages.csharp erhielt, um MyLib.ScenegraphUtil.Scenegraph und MyLib.ScenegraphUtil.* zu verwenden.

1

Just my 2 cents Hinzufügen:

ich die folgende Klasse hatte:

using Foo; 

public class Blah { 
    public void GetFoo(out Foo.Bar[] barArray) { 
    } 
} 

den Fehler verzeihend getFoo nicht zurückkehr die Ausgabe statt:

namespace Foo { 
    public struct Bar { 
    } 
    public class Foo { 
     //no method or member named "Bar" 
    } 
} 

Der Kunde wie folgt geschrieben wurde Um den Parameter out zu verwenden, konnte der Compiler den Datentyp Foo.Bar [] nicht auflösen. Es wurde der Fehler zurückgegeben: Typ oder Namespace Foo.Bar konnte nicht gefunden werden.

Es scheint, dass, wenn es versucht, es aufgelöst Foo als die Klasse zu kompilieren und nicht eine eingebettete Klasse Bar in der Klasse Foo gefunden. Es konnte auch keinen Namensraum namens Foo.Bar finden. Es konnte nicht nach einer Klassenleiste im Namensraum Foo gesucht werden. Die Punkte in einem Namensraum sind NICHT syntaktisch. Die ganze Zeichenfolge ist ein Token, nicht die durch die Punkte begrenzten Wörter.

Dieses Verhalten wurde von VS 2015 .Net 4.6

0

den gleichen Namen auf den Namespace Geben laufen ausgestellt und die Klasse kann der Compiler verwirren wie andere gesagt haben.

Wie heißt es dann?

Wenn der Namespace mehrere Klassen hat, suchen Sie einen Namen, der alle diese Klassen definiert.

Wenn der Namespace hat nur eine Klasse (und damit die Versuchung, sie den gleichen Namen zu geben) Namen der Namespace Class NS. So nennt Microsoft ihre Namespaces mindestens.

Verwandte Themen