Nur Namespace-Klassensichtbarkeit in C # /. NET?

87

Können Sie in C # eine Klasse nur in ihrem eigenen Namespace sichtbar machen, ohne in einer anderen Assembly zu leben? Dies scheint nützlich für typische Hilfsklassen zu sein, die nicht anderweitig verwendet werden sollten. (dh was Java paketprivate Klassen nennt)

nr
quelle
Ich verstehe deine Frage nicht. Ich habe meine Antworten entfernt, weil Sie nicht "intern" meinten?
Zyphrax
3
@nos: Suchen Sie das Äquivalent zur Sichtbarkeit auf Java-Paketebene?
John Saunders

Antworten:

35

Ich denke nicht, dass das, was du willst, möglich ist.

Steven Sudit
quelle
79

Sie können die Klassen erstellen internal, dies verhindert jedoch nur, dass Personen außerhalb der Assembly die Klasse verwenden. Sie müssen jedoch für jeden Namespace, mit dem Sie dies tun möchten , eine separate Assembly erstellen. Ich gehe davon aus, dass Sie es deshalb nicht wollen würden .

Den C # -Compiler dazu bringen, die Sichtbarkeit von Namespaces zu erzwingen

Hier gibt es einen Artikel ( Namespace-Sichtbarkeit in C # ), der eine Methode zur Verwendung von Teilklassen als Form eines "gefälschten Namespace" zeigt, die Sie möglicherweise hilfreich finden.

Der Autor weist darauf hin, dass dies nicht perfekt funktioniert und erörtert die Mängel. Das Hauptproblem ist, dass C # -Designer C # so entworfen haben, dass es nicht so funktioniert. Dies weicht stark von den erwarteten Codierungspraktiken in C # /. NET ab, was einer der größten Vorteile von .NET Frameworks ist.

Es ist ein ordentlicher Trick ... jetzt tu es nicht .

Robert Cartaino
quelle
1
System.Net.Mime.MediaTypeNames.Application
Habe
Der Artikel besagt, dass Sie jedem Anruf Ihren "Namespace" -Namen voranstellen müssen, aber das brauchen Sie bei C # 6 "using static" nicht. Sie können den "Namespace" zu einer statischen
Teilklasse
@Pumkko Die Klasse muss nicht statisch sein, um die Anweisung 'using static' verwenden zu können. Wenn Sie sie jedoch als Namespace verwenden, sollte sie es trotzdem sein.
Fuzzy Logic
21

Intern ist die Privatsphäre der Baugruppe (genau genommen Modul). Dies hat keine Auswirkungen auf die Sichtbarkeit von Namespaces.

Die einzige Möglichkeit, die Privatsphäre einer Klasse gegenüber anderen Klassen innerhalb derselben Assembly zu erreichen, besteht darin, dass eine Klasse eine innere Klasse ist.

Wenn die Klasse privat ist, ist sie zu diesem Zeitpunkt für alles unsichtbar, was nicht zu dieser Klasse oder zur äußeren Klasse selbst gehört.

Wenn es geschützt ist, ist es für alle sichtbar, die es privat sehen können, aber auch für Unterklassen der äußeren Klasse.

public class Outer
{
    private class Hidden     { public Hidden() {} }
    protected class Shady    { public Shady() {} }
    public class Promiscuous { public Promiscuous() {} }
}

public class Sub : Outer
{
    public Sub():base() 
    {
        var h = new Hidden();      // illegal, will not compile
        var s = new Shady();       // legal
        var p = new Promiscuous(); // legal
    }
}

public class Outsider 
{
    public Outsider() 
    {
        var h = new Outer.Hidden();      // illegal, will not compile
        var s = new Outer.Shady()        // illegal, will not compile
        var p = new Outer.Promiscuous(); // legal
    }
}

Im Wesentlichen besteht die einzige Möglichkeit, das zu erreichen, was Sie wünschen, darin, die äußere Klasse als Namespace zu verwenden und innerhalb dieser Klasse einzuschränken.

ShuggyCoUk
quelle
@ShuggyCoUK: öffentliche Klasse Sub: Outer sollte versiegelt werden öffentliche Klasse Sub: Outer ??? +1 obwohl ... es funktioniert für mich
IAbstract
0

Wenn Sie eine einzelne Assembly haben, können Sie so viele Namespaces in dieser Assembly definieren, wie Sie möchten. Unabhängig davon, welchen Modifikator Sie in der IDE anwenden, können Sie die Klassen immer in anderen Namespaces anzeigen.

Nathan
quelle
0

Ich bin mir nicht sicher, ob es direkt möglich ist, aber ein paar gute Möglichkeiten, es zu fälschen, wären:

1) Lassen Sie die Klassen, die solche Dinge benötigen, von einer einzelnen Klasse erben, die die Hilfsklasse als interne Klasse hat.

2) Verwenden Sie Erweiterungsmethoden und verweisen Sie dann nur auf die Erweiterungsmethoden im Namespace.

Wyatt Barnett
quelle