2009-06-30 9 views
29

Mi piacerebbe creare un auto-proprietà interna:Perché la protezione interna non è più restrittiva di quella interna?

internal bool IP { get; protected internal set; } 

ho pensato che sarebbe stato possibile fare il setter protected o protected internal - ma ottengo sempre l'accessibilità modificatore di errore deve essere più restrittiva della proprietà. Non è così? Private non mi aiuta, qui.

EDIT:
La domanda è: come faccio a implementare un auto-proprietà con un getter interno e un setter protetto?

+24

Il tuo errore è nel modo di pensare dei modificatori come _increasing_ restrizioni. I modificatori infatti limitano sempre _diminuire_. Ricorda, le cose sono "private" di default; solo aggiungendo i modificatori li rendi meno ristretti. –

+1

+1 - eric lippert lo metti sempre nel miglior modo possibile – JonH

+0

In realtà, la ** combinazione ** di modificatori è _decreasing_ restrizioni. Solo ** setting ** un modificatore è in effetti _increaseing_ le restrizioni come 'public bool IP {get; private set;} ' – Dani

risposta

49

È efficacemente protected o internal, non e. È accessibile sia per classi derivate e tipi nello stesso assembly. È un comune equivoco pensare che protected internal significhi accessibile solo alle classi derivate nello stesso assembly.

+1

OK, come posso rendere il getter interno e il setter protetti? – tanascius

+2

Non puoi. Il modificatore di accesso Getter/setter dovrebbe essere un sottoinsieme appropriato del modificatore di accesso proprietà. –

+2

Il mio problema è stato in realtà l'equivoco che ha protetto i mezzi interni protetti E interni - grazie per averlo sottolineato. – tanascius

2

protected internal è meno restrittiva rispetto sia protected o internal perché permette entrambe le sue sottoclassi (protected) e tutto nello stesso assieme (internal) per accedere qualcosa.

1

mezzi interni protetti visibili alle classi nello stesso assieme o alle classi derivanti dalla classe di contenimento - in altre parole è visibile a quelli che soddisfano i requisiti interni O i requisiti protetti, non AND. Non esiste un modificatore di accesso che sia protetto E interno in questo modo.

1

mezzi interni protetti protetti O interni, non protetti e interni. Quindi lo scope è limitato allo stesso assembly OR classi derivate, non necessariamente entrambi.

29

A livello NET, ci sono due simili ma distinti livelli di accesso:

  • FamilyAndAssembly: più restrittive rispetto sia protetto o interna
  • FamilyOrAssembly: meno restrittivo sia protetto o interna

"protected internal" in C# significa FamilyOrAssembly; non c'è alcun modificatore per FamilyAndAssembly.

Quindi, il setter protected internal è meno restrittivo della proprietà complessiva internal. Che cosa si potrebbe fare è:

protected internal bool IP { internal get; set; } 

Ma allora il tuo setter è meno limitata che il vostro getter, il che è strano ...

Altro (in qualche modo equivalente) alternativa è:

internal bool IP { get; set; } 

protected void SetIP(bool ip) 
{ 
    this.IP = ip; 
} 
+0

OK, la mia soluzione potrebbe essere una proprietà interna di sola lettura con un campo protetto. – tanascius

+0

Oppure la tua alternativa equivalente con un setter privato farebbe anche il lavoro. – tanascius

+0

Mi viene in mente, (mesi dopo naturalmente) che il setter è ancora accessibile "internamente" che è in qualche modo meno restrittivo che protetto. Per renderlo completamente un getter interno e un setter protetto, dovresti avere protetto SetIP (valore bool) e boo interno GetIP() vuoto e poi avere un bool privato _IP – DevinB

0

accessibilità modificatore deve essere più restrittiva della struttura

interno è mor e restrittivo quello protetto: perché le cose protette possono essere viste (per sottoclassi) al di fuori dell'assieme.

Il compilatore sta dicendo che non c'è alcun senso nel dire che set è protetto (cioè visibile alle sottoclassi di fuori del montaggio), quando l'intera proprietà è IP interna (cioè invisibile al di fuori del montaggio).

5

Considererei questo imbroglio, dal momento che Eric Lippert è su SO, ma ha scritto un post sul blog eccellente che considera questo problema.

Why Can't I Access A Protected Member From A Derived Class, Part Three

In ultima analisi, la sua risposta è in gran parte la stessa di quelle date dai manifesti qui, ma gli annunci qualche ragionamento interessante dietro il desgin della lingua e l'implementazione di queste caratteristiche.

+7

Non è "barare". Con tutti i mezzi, posta link. Mi fa risparmiare tempo. –

5

Considerando ciò che Jon Skeet ha menzionato (e il commento dell'utente59808), non otterrebbe il risultato desiderato?

protected internal bool IP { get; protected set; }

+0

Sì, è così che funziona. Thx – tanascius

+0

Sebbene la risposta scelta sia più esplicativa, vorrei che questa risposta fosse inclusa, come il cosa invece fare. –

Problemi correlati