Qual è la differenza tra "protetto" e "interno protetto"?


244

Qualcuno può per favore elaborarmi la differenza tra modificatori "protetti" e "protetti interni" in C #? Sembra che si comportino allo stesso modo.

Risposte:


402

Il modificatore di accesso "interno protetto" è un'unione di entrambi i modificatori "protetto" e "interno".

Da MSDN, modificatori di accesso (Guida per programmatori C #) :

protetto :

È possibile accedere al tipo o al membro solo tramite codice nella stessa classe o struttura o in una classe derivata da quella classe.

interno :

È possibile accedere al tipo o al membro da qualsiasi codice nello stesso assembly, ma non da un altro assembly.

interno protetto :

È possibile accedere al tipo o al membro da qualsiasi codice nell'assembly in cui viene dichiarato, O dall'interno di una classe derivata in un altro assembly. L'accesso da un altro assembly deve avvenire all'interno di una dichiarazione di classe che deriva dalla classe in cui viene dichiarato l'elemento interno protetto e deve avvenire attraverso un'istanza del tipo di classe derivata.

Notare che : protected internalsignifica " protectedOR internal" (qualsiasi classe nello stesso assembly o qualsiasi classe derivata, anche se si trova in un assembly diverso).

... e per completezza:

privato :

È possibile accedere al tipo o al membro solo tramite codice nella stessa classe o struttura.

pubblico :

È possibile accedere al tipo o al membro da qualsiasi altro codice nello stesso assembly o in un altro assembly a cui fa riferimento.

privato protetto :

L'accesso è limitato alla classe o ai tipi di contenimento derivati ​​dalla classe di contenimento all'interno dell'assembly corrente.
( Disponibile da C # 7.2 )


2
Posso avere un membro in protected internalmodo che sia protectednell'assembly corrente e completamente non disponibile esternamente?
Shimmy Weitzhandler,

8
Sarebbe "protetto", no?
Bloke CAD,

2
@Shimmy: puoi avere una classe interna con metodi protetti . Ma poi l'intera classe non sarà disponibile da assiemi esterni.
M4N,

1
@Shimmy dai un'occhiata a questa proposta per una versione futura di C # github.com/dotnet/roslyn/blob/features/privateProtected/docs/…
Nate Cook,

@Shimmy Almeno CLR supporta il concetto di intersezione di accessibilità protetta e interna, ma il linguaggio C # no. C # supporta solo l'unione dei due modificatori di accesso.
RBT,

89

protected può essere utilizzato da qualsiasi sottoclasse di qualsiasi assembly.

protected internalè tutto ciò che protectedè, più anche qualsiasi cosa nello stesso assembly può accedervi.

È importante sottolineare che non significa "sottoclassi nello stesso assieme": è l'unione dei due, non l'intersezione.


3
Solo un FYI per i lettori che CLR supporta anche il concetto di intersezione di accessibilità protetta e interna, ma C # non lo supporta. C # supporta solo l'unione dei due come menzionato in questo post.
RBT,

1
Solo un'altra FYI per i lettori, "sottoclassi nello stesso assembly" possono essere raggiunte con il private protectedmodificatore di accesso introdotto in C # 7.2
LordWilmore,

52

- Aggiorna risposta 2019 -

Puoi trovare la differenza nella seguente accessibilità basata su tabella è sì,

inserisci qui la descrizione dell'immagine


4
Bella risposta, comunica in modo molto chiaro le differenze tra ciascun modificatore di accesso.
e_i_pi,

23

In pratica, sui metodi:

protetto - accessibile per classi ereditate, altrimenti privato.

interno - pubblico solo per le classi all'interno dell'assemblea, altrimenti privato.

metodi interni protetti - significa che i metodi protetti o interni diventano accessibili per le classi ereditate e per tutte le classi all'interno dell'assembly.


1
Vorrei usare OR per esprimere quella causa o non deve essere vero per entrambi.
Brian Rasmussen,

Non sono completamente d'accordo con la parte "per modificare il comportamento della classe di base" nella descrizione di "protetto". Direi che è qui che usi "virtuale" (nella classe base) e "ignora" (nella classe derivata).
M4N,

C'è un modo per contrassegnare un membro come protectedAND internal?
Shimmy Weitzhandler,

@Shimmy: si protected internal.
abatishchev,

1
@Shimmy due anni dopo, e sì. Ora c'è un modo in C # 7.2. Si chiama private protected docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
Pauli Østerø

10

C'è ancora molta confusione nella comprensione dell'ambito degli accessori "interni protetti", sebbene la maggior parte abbia la definizione definita correttamente. Questo mi ha aiutato a capire la confusione tra "protetto" e "interno protetto":

pubblico è veramente pubblico dentro e fuori l'assemblea ( pubblico interno / pubblico esterno )

protetto è realmente protetto all'interno e all'esterno dell'assieme ( protetto interno / protetto esterno ) (non consentito nelle classi di livello superiore)

private è veramente privato all'interno e all'esterno dell'assembly ( privato interno / privato esterno ) (non consentito nelle classi di livello superiore)

interno è veramente pubblico all'interno dell'assemblea ma escluso all'esterno dell'assemblea come privato ( pubblico interno / escluso esterno )

l'interno protetto è realmente pubblico all'interno dell'assemblaggio ma protetto all'esterno dell'assemblea ( interno pubblico / esterno protetto ) (non consentito nelle classi di livello superiore)

Come puoi vedere, l' interno protetto è una strana bestia. Non intuitivo

Ciò pone ora la domanda perché Microsoft non ha creato un ( protetto interno / escluso esterno ), o immagino che una sorta di "protetto privato" o "protetto interno"? lol. Sembra incompleto?

Alla confusione si aggiunge il fatto che è possibile nidificare membri nidificati interni pubblici o protetti all'interno di tipi protetti, interni o privati. Perché dovresti accedere a un "interno protetto" nidificato all'interno di una classe interna che esclude l'accesso all'esterno dell'assembly?

Microsoft afferma che tali tipi nidificati sono limitati dall'ambito del loro tipo parent, ma non è quello che dice il compilatore. È possibile compilare interni protetti all'interno di classi interne che dovrebbero limitare l'ambito al solo assieme.

Per me questo sembra un design incompleto. Dovrebbero avere una portata semplificata di tutti i tipi in un sistema che consideri chiaramente l'ereditarietà ma anche la sicurezza e la gerarchia dei tipi nidificati. Ciò avrebbe reso la condivisione di oggetti estremamente intuitiva e granulare piuttosto che scoprire l'accessibilità di tipi e membri basata su un sistema di scoping incompleto.


1
la protezione privata è stata ora aggiunta a C # 7.2 che è sostanzialmente interna E protetta.
Pauli Østerø

7

protetto : la variabile o il metodo saranno disponibili solo per le classi figlio (in qualsiasi assembly)

interno protetto : disponibile per le classi figlio in qualsiasi assembly e per tutte le classi all'interno dello stesso assembly


3

Ho letto definizioni molto chiare per questi termini.

Protetto: l'accesso è limitato alla definizione della classe e a qualsiasi classe che eredita dalla classe. È possibile accedere al tipo o al membro solo tramite codice nella stessa classe o struttura o in una classe derivata da quella classe.

Interno: l'accesso è limitato esclusivamente alle classi definite nell'assemblea del progetto corrente. È possibile accedere al tipo o al membro solo tramite il codice nella stessa classe.

Protetto-interno: l'accesso è limitato all'assembly corrente o ai tipi derivati ​​dalla classe contenente.


1

Membro protetto

Membro protetto di una classe disponibile solo nella classe contenuta (in cui è stata dichiarata) e nella classe derivata all'interno dell'assembly e anche all'esterno dell'assembly.

Indica se una classe che risiede all'esterno dell'assembly può utilizzare il membro protetto dell'altro assembly ereditando solo quella classe.

È possibile esporre il membro protetto all'esterno dell'assembly ereditando quella classe e utilizzarlo solo nella classe derivata.

Nota: i membri protetti non sono accessibili utilizzando l'oggetto nella classe derivata.

Membro interno

Il membro interno di una classe è disponibile o l'accesso all'interno dell'assembly creando l'oggetto o in una classe derivata oppure si può dire che è accessibile da tutte le classi all'interno dell'assembly.

Nota: i membri interni non accessibili all'esterno dell'assembly utilizzando la creazione di oggetti o in una classe derivata.

Interno protetto

Il modificatore di accesso interno protetto è una combinazione protetta o interna.

Il Membro interno protetto può essere disponibile all'interno dell'intero assembly in cui ha dichiarato di creare l'oggetto o ereditare quella classe. E può essere accessibile all'esterno dell'assembly solo in una classe derivata.

Nota: il membro interno protetto funziona come interno all'interno dello stesso assieme e funziona come protetto all'esterno dell'assieme.


1

pubblico : i membri (Funzioni e variabili) dichiarati come pubblici sono accessibili da qualsiasi luogo.

privato : non è possibile accedere ai membri privati ​​al di fuori della classe. Questo è l'identificatore di accesso predefinito per un membro, ovvero se non si specifica un identificatore di accesso per un membro (variabile o funzione), verrà considerato privato. Pertanto, stringa PhoneNumber; è equivalente alla stringa privata PhoneNumber.

protetto : è possibile accedere ai membri protetti solo dalle classi secondarie.

interno : è possibile accedervi solo all'interno dello stesso assieme.

interno protetto : è possibile accedervi all'interno dello stesso assembly e anche nella classe derivata.


0

Le migliori suite interne protette quando si desidera che un membro o un tipo vengano utilizzati in una classe derivata da un altro assembly allo stesso tempo, si desideri semplicemente consumare il membro o il tipo nell'assembly padre senza derivare dalla classe in cui viene dichiarato. Inoltre, se si desidera utilizzare solo un membro o un tipo senza derivare da un'altra classe, nello stesso assembly è possibile utilizzare solo interni.

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.