Qual è il modificatore di accesso predefinito per classi, metodi, membri, costruttori, delegati e interfacce?
Qual è il modificatore di accesso predefinito per classi, metodi, membri, costruttori, delegati e interfacce?
Risposte:
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.)
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!
class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();
, non è possibile accedere M
con a.M()
, tuttavia è possibile accedervi con (a as IFoo).M()
. (Controlla le specifiche per maggiori informazioni sulle specifiche)
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 ...)
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.
La classe è interna 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.
Vorrei aggiungere un collegamento alla documentazione. Scopri maggiori dettagli qui .
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.