Visibilità della classe solo spazio dei nomi in C # /. NET?


88

In C #, è possibile rendere visibile una classe solo all'interno del proprio spazio dei nomi senza risiedere in un assembly diverso? Questo sembra utile per le classi helper tipiche che non dovrebbero essere usate altrove. (cioè ciò che Java chiama classi private del pacchetto)


Non capisco la tua domanda. Ho rimosso le mie risposte perché non intendevi "interno"?
Zyphrax

3
@nos: stai cercando l'equivalente della visibilità a livello di pacchetto di java?
John Saunders

Risposte:



80

Puoi creare le classi internalma questo impedisce solo a chiunque al di fuori dell'assembly di utilizzare la classe. Ma devi ancora creare un assembly separato per ogni spazio dei nomi con cui vuoi farlo. Suppongo che sia per questo che non lo faresti vorresti farlo.

Ottenere il compilatore C # per applicare la visibilità dello spazio dei nomi

C'è un articolo qui ( visibilità dello spazio dei nomi in C # ) che mostra un metodo per utilizzare le classi parziali come una forma di "spazio dei nomi falso" che potresti trovare utile.

L'autore sottolinea che questo non funziona perfettamente e discute le carenze. Il problema principale è che i designer di C # hanno progettato C # per non funzionare in questo modo. Ciò si discosta notevolmente dalle pratiche di codifica previste in C # /. NET, che è uno dei maggiori vantaggi di .NET Framework.

È un bel trucco ... ora non farlo.


1
Ho appena trovato un esempio:System.Net.Mime.MediaTypeNames.Application
Bitterblue

L'articolo dice che devi anteporre a ogni chiamata il nome del tuo "spazio dei nomi", ma non ne hai bisogno con C # 6 "using static". Puoi rendere lo "spazio dei nomi" una classe parziale statica e quindi nel codice client scrivere "using static"
Pumkko

@Pumkko La classe non ha bisogno di essere statica per poter usare l'istruzione "using static", anche se se la stai usando come spazio dei nomi dovrebbe essere comunque.
Fuzzy Logic

21

interno è la privacy dell'assemblaggio (modulo in senso stretto). Non ha alcun effetto sulla visibilità dello spazio dei nomi.

L'unico modo per ottenere la privacy di una classe da altre classi all'interno dello stesso assembly è che una classe sia una classe interna.

A questo punto, se la classe è privata, è invisibile a qualsiasi cosa non in quella classe o nella stessa classe esterna.

Se protetto è visibile a tutti coloro che potrebbero vederlo quando è privato, ma è anche visibile alle sottoclassi della classe esterna.

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

In sostanza, l'unico modo per ottenere ciò che desideri è usare la classe esterna come una forma di spazio dei nomi e limitare all'interno di quella classe.


@ShuggyCoUK: public class Sub: Outer dovrebbe essere sigillato public class Sub: Outer ??? +1 però ... per me funziona
IAbstract

0

Se hai un singolo assembly puoi definire tutti gli spazi dei nomi che desideri in quell'assembly, ma indipendentemente dal modificatore applicato nell'IDE, sarai sempre in grado di vedere le classi in altri spazi dei nomi.


0

Non sono sicuro che sia direttamente possibile, ma alcuni buoni modi per fingere sarebbe:

1) Fai in modo che le classi che necessitano di questo genere di cose ereditino da una singola classe che ha la classe helper come classe interna.

2) Utilizzare metodi di estensione e quindi fare riferimento solo ai metodi di estensione all'interno dello spazio dei nomi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.