Qual è il significato del modificatore di accesso C # "protetto privato" pianificato?


133

Come parte della documentazione di Roslyn su GitHub, c'è una pagina chiamata Stato dell'implementazione delle funzionalità del linguaggio , con funzionalità di lingua pianificate per C # e VB.

Una caratteristica che non riuscivo a comprendere è il private protectedmodificatore di accesso:

private protected string GetId() {  } 

C'è anche una pagina di C # Language Design Notes , che spiega molte nuove funzionalità, ma non questa.

Eric Lippert ha detto in un commento :

Il tuo errore sta nel considerare i modificatori come restrizioni crescenti. I modificatori infatti diminuiscono sempre le restrizioni. Ricorda, le cose sono "private" per impostazione predefinita; solo aggiungendo modificatori li rendi meno limitati.

Qual è il significato di private protected? Quando potrei usarlo?


2
Si noti che ci sono informazioni al riguardo nelle note di progettazione del linguaggio VB .
Jesse Good,

3
È una mappatura su MethodAttributes.FamANDAssem. C # ha una strana mappatura di interni , usa (Private | FamANDAssem). E mappe interne protette a (Privato | Famiglia). Gli attributi CLR sono strani.
Hans Passant,

22
Questa funzione proposta renderà il mio commento errato.
Eric Lippert,

Il team di progettazione di C # ha pubblicato un sondaggio con una sintassi alternativa suggerita per questa funzione. Alcuni di questi sono interessanti, come protected & internal, assembly protectedo proternal(spero che alcuni di questi siano scherzi). C'è anche il thread di discussione con alcune belle intuizioni.
Kobi,

1
La funzione è ora contrassegnata come ritirata nello stato di implementazione della funzione lingua! Personalmente mi piace l'idea di questo livello di accesso e penso che sia una funzione utile. Voglio usare il protetto per mantenere il mio codice secondo il design della classe, ma non voglio che altri scrivano sottogruppi disordinati che hanno accesso a questi membri. IMO la soluzione migliore sarebbe se potessimo scrivere protected | internaleprotected & internal
Felix Keil,

Risposte:


98

Secondo " Professional C # 2008 " di De Bill Evjen e Jay Glynn, pagina 1699:

protetto privato - "solo tipi derivati ​​all'interno dell'assembly corrente"

C ++ / CLI ha una funzione simile - Definire e consumare classi e strutture (C ++ / CLI)> Visibilità dei membri :

private protectedprotected private- oppure - Il membro è protetto all'interno dell'assembly ma privato all'esterno dell'assembly.


72
Quindi è "protetto e interno" anziché "protetto o interno"?
user541686

2
Sarà ora possibile far accettare o restituire cose di internaltipo a un membro accessibile alle classi derivate senza richiedere che il membro sia esposto a tutto ciò che fa parte dell'assemblaggio?
supercat

Grazie! Non ci ho pensato. In realtà ho dei casi in cui avrei usato quel modificatore, e sono tornato indietro internal.
Kobi,

3
L'esistenza di questa proposta / caratteristica sembra suggerire che la internalvisibilità (correlata al punto in cui è definita la classe) sia realmente ortogonale alla public/ protected/ privatevisibilità (legata all'eredità) e che, forse, internaldovrebbe essere il proprio modificatore separato da public/ protected/ private.
jpmc26

1
@jww - Non ho molta familiarità con Java, ma per quanto ne so packagein Java è più simile allo spazio dei nomi in C #.
Gogutz,


28

Questo serve solo a fornire un grafico (realizzato con http://ashitani.jp/gv/ ) dei diversi livelli di accessibilità (le immagini non si adattano ai commenti).

diagramma di digraph dei livelli di accesso C #

Ogni freccia significa "è più restrittivo di".

I nomi CLR sono Private, FamilyANDAssembly, Assembly, Family, FamilyORAssembly, Public.


Modifica molto più tardi: si è scoperto che questo nuovo livello di accesso (con un nome davvero scadente) non è stato infine incluso in C # 6.0. È supportato solo da C # 7.2 (e vedo che hai aggiornato la tua domanda "tag").


Potrei essere solo io, ma le frecce sembrano andare nella direzione "meno restrittiva di".
acarlon

4
@acarlon Sì, quindi a → bnel diagramma significa " aè più restrittivo di b", quindi puoi "leggere" la freccia come "è più restrittivo di" (era quello che ho cercato di spiegare), quindi la freccia indica il meno restrittivo " direzione". La convenzione opposta per le frecce avrebbe potuto essere altrettanto buona, comunque, ma ho dovuto scegliere una convenzione.
Jeppe Stig Nielsen

10

È solo un'ipotesi, ma da un nome si potrebbe immaginare che sia una versione più limitata di protected(o versione più rilassata di privatese lo si desidera). E solo una ragionevole variante di esso sta limitando il protectedcomportamento all'assemblaggio.

Possibile utilizzo: quindi si desidera avere protectedun'implementazione interna, ma non per usi esterni (e non si desidera sigillare la classe).

PS È sempre esistito in CLR, ma non in C # . È una combinazione di protected e internal , citazione:

CLR supporta anche il tipo di accesso "Famiglia e assemblaggio". Ciò significa che il metodo è accessibile dal tipo dichiarante, dai tipi nidificati e derivati, ma solo se sono dichiarati nello stesso assembly. Beh, a quanto pare il team C # non l'ha considerata una funzionalità molto utile, quindi non è supportata in questa lingua.


+1 per il commento CLR - Trascorro così tanto tempo in C # e così poco negli altri linguaggi .NET in questi giorni che a volte dimentico che non sono la stessa cosa.
brichins,

@DarrelHoffman grazie per averlo notato! Ho confuso un po 'i miei pensieri qui)
Petr Abdulin il

5

"Può essere" visibile solo alle sottoclassi che si trovano nello stesso assembly. Questo lo rende un po 'limitato di protected.


1

Vedi le specifiche per la funzione "protezione privata":

Il significato intuitivo di privato protetto è "accessibile all'interno di questo assembly da tipi derivati ​​dalla classe contenente".

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.