Quali sono i modificatori di accesso predefiniti in C #?


384

Qual è il modificatore di accesso predefinito per classi, metodi, membri, costruttori, delegati e interfacce?

Risposte:


486

L'accesso predefinito per tutto in C # è "l'accesso più limitato che potresti dichiarare per quel membro" .

Quindi per esempio:

namespace MyCompany
{
    class Outer
    {
        void Foo() {}
        class Inner {}
    }
}

è equivalente a

namespace MyCompany
{
    internal class Outer
    {
        private void Foo() {}
        private class Inner {}
    }
}

L'unico tipo di eccezione a questo è rendere una parte di una proprietà (di solito il setter) più limitata dell'accessibilità dichiarata della proprietà stessa:

public string Name
{
    get { ... }
    private set { ... } // This isn't the default, have to do it explicitly
}

Questo è ciò che la specifica C # 3.0 ha da dire (sezione 3.5.1):

A seconda del contesto in cui si svolge la dichiarazione di un membro, sono consentiti solo alcuni tipi di accessibilità dichiarata. Inoltre, quando una dichiarazione del membro non include alcun modificatore di accesso, il contesto in cui ha luogo la dichiarazione determina l'accessibilità dichiarata predefinita.

  • Gli spazi dei nomi implicitamente hanno un'accessibilità dichiarata pubblica. Non sono consentiti modificatori di accesso nelle dichiarazioni dello spazio dei nomi.
  • I tipi dichiarati in unità di compilazione o spazi dei nomi possono avere accessibilità dichiarata pubblica o interna e impostazione predefinita per l'accessibilità dichiarata interna.
  • I membri della classe possono avere uno dei cinque tipi di accessibilità dichiarata e impostazione predefinita per l'accessibilità dichiarata privata. (Si noti che un tipo dichiarato come membro di una classe può avere uno dei cinque tipi di accessibilità dichiarata, mentre un tipo dichiarato come membro di uno spazio dei nomi può avere solo accessibilità dichiarata pubblica o interna.)
  • I membri di Struct possono avere accessibilità dichiarata pubblica, interna o privata e impostazione predefinita per l'accessibilità dichiarata privata poiché le strutture sono implicitamente sigillate. I membri Struct introdotti in una struttura (ovvero non ereditata da quella struttura) non possono avere un'accessibilità dichiarata interna protetta o protetta. (Notare che un tipo dichiarato come membro di una struttura può avere accessibilità dichiarata pubblica, interna o privata, mentre un tipo dichiarato come membro di uno spazio dei nomi può avere solo accessibilità dichiarata pubblica o interna.)
  • I membri dell'interfaccia implicitamente hanno un'accessibilità dichiarata pubblica. Non sono consentiti modificatori di accesso nelle dichiarazioni dei membri dell'interfaccia.
  • I membri dell'enumerazione implicitamente hanno un'accessibilità dichiarata pubblica. Non sono consentiti modificatori di accesso nelle dichiarazioni dei membri di enumerazione.

(Si noti che i tipi nidificati rientrerebbero nelle parti "membri della classe" o "membri della struttura" - e quindi per impostazione predefinita alla visibilità privata.)


154
top level class: internal
method: private
members (unless an interface or enum): private (including nested classes)
members (of interface or enum): public
constructor: private (note that if no constructor is explicitly defined, a public default constructor will be automatically defined)
delegate: internal
interface: internal
explicitly implemented interface member: public!

13
Questo non chiarisce che se una classe è anche un membro (a causa del tipo nidificato), per impostazione predefinita è privato. Inoltre, i membri di un'interfaccia e di un enum sono sempre pubblici.
Jon Skeet,

1
@niry No, non è privato. È pubblico. Semplicemente non avere una fessura nel tipo di applicazione, in modo da se class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();, non è possibile accedere Mcon a.M(), tuttavia è possibile accedervi con (a as IFoo).M(). (Controlla le specifiche per maggiori informazioni sulle specifiche)
M. Stramm

130

Risposta breve: accesso minimo possibile (vedi la risposta di Jon Skeet).

Risposta lunga:

Tipi non annidati , enumerazione e accessibilità dei delegati ( possono avere solo accessibilità interna o pubblica )

                     | Default   | Permitted declared accessibilities
------------------------------------------------------------------
namespace            | public    | none (always implicitly public)

enum                 | public    | none (always implicitly public)

interface            | internal  | public, internal

class                | internal  | public, internal

struct               | internal  | public, internal

delegate             | internal  | public, internal

Tipo nidificato e accessibilità dei membri

                     | Default   | Permitted declared accessibilities
------------------------------------------------------------------
namespace            | public    | none (always implicitly public)

enum                 | public    | none (always implicitly public)

interface            | public    | none

class                | private   | All¹

struct               | private   | public, internal, private²

delegate             | private   | All¹

constructor          | private   | All¹

interface member     | public    | none (always implicitly public)

method               | private   | All¹

field                | private   | All¹

user-defined operator| none      | public (must be declared public)

¹ Tutti === pubblico, protetto, interno, privato, interno protetto

² Le strutture non possono ereditare da strutture o classi (sebbene possano, interfacce), quindi il protetto non è un modificatore valido

L'accessibilità di un tipo nidificato dipende dal suo dominio di accessibilità, che è determinato sia dall'accessibilità dichiarata del membro sia dal dominio di accessibilità del tipo immediatamente contenente. Tuttavia, il dominio di accessibilità di un tipo nidificato non può superare quello del tipo contenente.

Nota: CIL ha anche la disposizione per protetto e interno (al contrario dell'attuale protezione "o" interna), ma per quanto ne so, questo non è attualmente disponibile per l'uso in C #.


Vedere:

http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
http://msdn.microsoft.com/en-us/library/ms173121.aspx
http://msdn.microsoft.com/en- us / library / cx03xt0t.aspx
(Man I love Microsoft URIs ...)


12

Dai un'occhiata ai modificatori di accesso (Guida per programmatori C #)

Accessibilità per classi e strutture

Le classi e le strutture dichiarate direttamente all'interno di uno spazio dei nomi (in altre parole, che non sono nidificate all'interno di altre classi o strutture) possono essere pubbliche o interne. Interno è l'impostazione predefinita se non viene specificato alcun modificatore di accesso.

I membri di Struct, comprese le classi e le strutture nidificate, possono essere dichiarati come pubblici, interni o privati. I membri della classe, comprese le classi e le strutture nidificate, possono essere pubblici, interni protetti, protetti, interni, privati ​​protetti o privati. Il livello di accesso per i membri della classe e membri della struttura, comprese le classi e le strutture nidificate, è privato per impostazione predefinita. I tipi nidificati privati ​​non sono accessibili dall'esterno del tipo contenente.

Le classi derivate non possono avere una maggiore accessibilità rispetto ai loro tipi di base. In altre parole, non è possibile avere una classe pubblica B che deriva da una classe interna A. Se ciò fosse consentito, avrebbe l'effetto di rendere pubblico A, poiché tutti i membri protetti o interni di A sono accessibili dalla classe derivata.

È possibile abilitare altri specifici assiemi per accedere ai tipi interni utilizzando il InternalsVisibleToAttribute. Per ulteriori informazioni, consultare Assemblee di amici.

Accessibilità dei membri Class e Struct

I membri della classe (comprese le classi e le strutture nidificate) possono essere dichiarati con uno dei sei tipi di accesso. I membri di Struct non possono essere dichiarati come protetti perché le strutture non supportano l'ereditarietà.

Normalmente, l'accessibilità di un membro non è maggiore dell'accessibilità del tipo che lo contiene. Tuttavia, un membro pubblico di una classe interna potrebbe essere accessibile dall'esterno dell'assembly se il membro implementa metodi di interfaccia o sovrascrive metodi virtuali definiti in una classe di base pubblica.

Il tipo di qualsiasi membro che è un campo, proprietà o evento deve essere accessibile almeno quanto il membro stesso. Allo stesso modo, il tipo restituito e i tipi di parametro di qualsiasi membro che sia un metodo, un indicizzatore o un delegato devono essere accessibili almeno quanto il membro stesso. Ad esempio, non è possibile avere un metodo pubblico M che restituisce una classe C a meno che C sia anche pubblico. Allo stesso modo, non è possibile avere una proprietà protetta di tipo A se A viene dichiarato privato.

Gli operatori definiti dall'utente devono essere sempre dichiarati come pubblici e statici. Per ulteriori informazioni, consultare Sovraccarico dell'operatore.

I finalizzatori non possono avere modificatori dell'accessibilità.

Altri tipi

Le interfacce dichiarate direttamente all'interno di uno spazio dei nomi possono essere dichiarate come pubbliche o interne e, proprio come le classi e le strutture, le interfacce sono predefinite per l'accesso interno. I membri dell'interfaccia sono sempre pubblici perché lo scopo di un'interfaccia è consentire ad altri tipi di accedere a una classe o struttura. Non è possibile applicare modificatori di accesso ai membri dell'interfaccia.

I membri dell'enumerazione sono sempre pubblici e non è possibile applicare modificatori di accesso.

I delegati si comportano come classi e strutture. Per impostazione predefinita, hanno accesso interno quando dichiarato direttamente all'interno di uno spazio dei nomi e accesso privato quando nidificato.


8

La classe è interna per impostazione predefinita.

  • I membri della classe sono privati per impostazione predefinita.

L'interfaccia è interna per impostazione predefinita.

  • I membri dell'interfaccia sono pubblici per impostazione predefinita. (Le interfacce non ci consentiranno di specificare alcun tipo di accessibilità ai suoi membri.)

    Nota: se si tenta di specificare qualsiasi identificatore di accesso ai membri dell'interfaccia, verrà visualizzato l'errore di compilazione.

Struct è Interno per impostazione predefinita.

  • I membri di Struct sono privati per impostazione predefinita.

5

Vorrei aggiungere un collegamento alla documentazione. Scopri maggiori dettagli qui .

inserisci qui la descrizione dell'immagine


1
la classe è di default interna e non privata.
Baahubali,

1
Dove ho scritto la lezione è privata?
Asif Mushtaq,

Questa tabella è valida solo per i tipi nidificati.
BlueSilver,

la classe è interna per impostazione predefinita e la classe nello spazio dei nomi non può essere privata. ma la classe all'interno di una classe (classe nidificata) può essere privata
Arun,

Il modificatore di accesso all'interfaccia è Interno per impostazione predefinita.
Kamala Hanchinal,

4

La risposta più semplice è la seguente .....

Tutti i membri in C # accettano sempre il modificatore accessibile LEAST per impostazione predefinita.

Questo è il motivo per cui tutte le classi di livello superiore in un assembly sono "interne" per impostazione predefinita, il che significa che sono pubbliche per l'assembly in cui si trovano, ma private o escluse dall'accesso agli assembly esterni. L'unica altra opzione per una classe di livello superiore è pubblica che è più accessibile. Per i tipi nidificati è tutto privato tranne alcune rare eccezioni come membri di enumerazioni e interfacce che possono essere solo pubbliche. Qualche esempio. Nel caso di classi e interfacce di livello superiore, i valori predefiniti sono:

classe Animale uguale alla classe interna Animale

interfaccia Animale uguale all'interfaccia pubblica Animale

Nel caso di classi e interfacce nidificate (tipi interni), i valori predefiniti sono:

classe Animale uguale alla classe privata Animale

interfaccia Animale uguale all'interfaccia privata Animale

Se si presume che il valore predefinito sia sempre il più privato, non è necessario utilizzare un accessorio finché non è necessario modificare il valore predefinito. Facile.



0

Livello di spazio dei nomi: internal

Livello di tipo: private

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.