Qual é o significado do modificador de acesso C # "protegido privado" planejado?

133

Como parte da documentação do Roslyn no GitHub, existe uma página chamada Status de implementação do recurso de idioma , com recursos de idioma planejado para C # e VB.

Um recurso que eu não conseguia entender era o private protectedmodificador de acesso:

private protected string GetId() {  } 

Há também uma página do C # Language Design Notes , que explica muitos novos recursos, mas não este.

Eric Lippert disse em um comentário :

Seu erro é pensar nos modificadores como restrições crescentes. Na verdade, os modificadores sempre diminuem as restrições. Lembre-se, as coisas são "privadas" por padrão; somente adicionando modificadores você os torna menos restritos.

Qual é o significado de private protected? Quando devo usá-lo?

Kobi
fonte
2
Observe que há informações sobre isso nas notas de design do idioma do VB .
Jesse Boa
3
É um mapeamento para MethodAttributes.FamANDAssem. C # tem um mapeamento estranho de interno , ele usa (Privado | FamANDAssem). E mapas protegidos internos para (Privado | Família). Os atributos do CLR são estranhos.
Hans Passant
22
Esse recurso proposto tornará meu comentário incorreto.
precisa
A equipe de design do C # publicou uma pesquisa com sintaxe alternativa sugerida para esse recurso. Alguns deles são interessantes, tipo protected & internal, assembly protectedou proternal(espero que alguns sejam piadas). Há também o tópico de discussão com algumas idéias interessantes.
Kobi
1
O recurso agora está marcado como retirado no status de implementação do recurso de idioma! Pessoalmente, gosto da ideia desse nível de acesso e acho que é um recurso útil. Quero usar o protected para manter meu código de acordo com o design da classe, mas não quero que outras pessoas escrevam sublasses hacky que tenham acesso a esses membros. IMO a melhor solução seria se pudéssemos escrever protected | internaleprotected & internal
Felix Keil

Respostas:

98

De acordo com o " Professional C # 2008 " de De Bill Evjen e Jay Glynn, página 1699:

private protected - "apenas tipos derivados no assembly atual"

O C ++ / CLI possui um recurso semelhante - Definir e consumir classes e estruturas (C ++ / CLI)> Visibilidade do membro :

private protectedprotected private- ou - - Membro é protegido dentro da montagem, mas privado fora da montagem.

Gogutz
fonte
72
Então é "protegido e interno" em vez de "protegido ou interno"?
precisa saber é o seguinte
2
Agora será possível ter um membro que é acessível para classes derivadas aceitar ou retornar itens do internaltipo sem exigir que ele seja exposto a tudo na montagem?
supercat
Obrigado! Eu não pensei sobre isso. Na verdade, tenho casos em que teria usado esse modificador e voltei a usá-lo internal.
Kobi
3
A existência dessa proposta / recurso parece sugerir que a internalvisibilidade (relacionada a onde a classe é definida) é realmente ortogonal a public/ protected/ privatevisibilidade (relacionada a herança) e que, talvez, internaldeva ser seu próprio modificador separado de public/ protected/ private.
precisa saber é o seguinte
1
@ jww - Eu não estou muito familiarizado com Java, mas tanto quanto eu sei packageem Java é mais como espaço para nome em C #.
Gogutz
187

Aqui estão todos os modificadores de acesso nos diagramas de Venn, de mais limitantes a mais promíscuos:

private:
insira a descrição da imagem aqui

private protected: - adicionado no C # 7.2
insira a descrição da imagem aqui

internal:
insira a descrição da imagem aqui

protected:
insira a descrição da imagem aqui

protected internal:
insira a descrição da imagem aqui

public:
insira a descrição da imagem aqui

Kobi
fonte
3
Imagem de origem: Access Modifiers.pdn . Eu usei o apropriadamente chamado Paint.Net .
Kobi
9
Onde esses diagramas estiveram toda a minha vida (C #)? Eles são excelentes - obrigado!
Jon Peterson
28

Isso serve apenas para fornecer um gráfico (feito com http://ashitani.jp/gv/ ) dos diferentes níveis de acessibilidade (as imagens não se encaixam nos comentários).

diagrama digigráfico dos níveis de acesso em C #

Cada seta significa "é mais restritivo que".

Os nomes CLR são Private, FamilyANDAssembly, Assembly, Family, FamilyORAssembly, Public.


Edição muito mais tarde: o novo nível de acesso (com um nome muito ruim) acabou não sendo incluído no C # 6.0. É suportado apenas no C # 7.2 (e vejo que você atualizou sua pergunta "tags").

Jeppe Stig Nielsen
fonte
Pode ser apenas eu, mas as flechas parecem estar indo na direção 'menos restritiva que'.
Acarlon
4
@acarlon Sim, então a → bno diagrama significa " aé mais restritivo que b", para que você possa "ler" a seta como "é mais restritivo que" (foi o que tentei explicar), de modo que a seta aponta para o menos restritivo " direção". A convenção oposta para as flechas poderia ter sido igualmente boa, a propósito, mas eu tive que escolher uma convenção.
Jeppe Stig Nielsen
10

É apenas um palpite, mas, a partir de um nome, você pode adivinhar que é uma versão mais restrita protected(ou mais descontraída, privatese desejar). E apenas uma variante razoável disso está restringindo o protectedcomportamento à montagem.

Uso possível: então você quer ter protectedpara implementação interna, mas não para usos externos (e não deseja selar a classe).

PS: Ele sempre existiu no CLR, mas não no C # . É uma combinação de protected e internal , citação:

O CLR também suporta o tipo de acesso "Família e montagem". Isso significa que o método pode ser acessado no tipo de declaração, tipos aninhados e derivados, mas apenas se eles forem declarados no mesmo assembly. Bem, aparentemente a equipe do C # não considerou isso um recurso muito útil, portanto não é suportado neste idioma.

Petr Abdulin
fonte
+1 no comentário do CLR - hoje passo tanto tempo em C # e tão pouco nas outras linguagens .NET que às vezes esqueço que elas não são a mesma coisa.
Brichins # 9/14
@DarrelHoffman obrigado por notar! Eu misturei meus pensamentos aqui um pouco)
Petr Abdulin
5

"Pode ser" visível apenas para subclasses que estão no mesmo assembly. Isso torna um pouco restrito que protected.

Mehmet Ataş
fonte
1

Veja a especificação do recurso "protegido particular":

O significado intuitivo de private protected é "acessível neste assembly por tipos derivados da classe que o contém".

Julien Couvreur
fonte