Qual é a diferença entre 'protected' e 'protected internal'?

244

Alguém pode me explicar a diferença entre os modificadores 'protected' e 'protected internal' em C #? Parece que eles se comportam da mesma maneira.

Embedd_Khurja
fonte

Respostas:

402

O modificador de acesso "protegido interno" é uma união dos modificadores "protegido" e "interno".

No MSDN, Modificadores de Acesso (Guia de Programação em C #) :

protegido :

O tipo ou membro pode ser acessado apenas por código na mesma classe ou estrutura ou em uma classe derivada dessa classe.

interno :

O tipo ou membro pode ser acessado por qualquer código no mesmo assembly, mas não de outro assembly.

interno protegido :

O tipo ou membro pode ser acessado por qualquer código no assembly no qual é declarado, OU de dentro de uma classe derivada em outro assembly. O acesso de outro assembly deve ocorrer dentro de uma declaração de classe derivada da classe na qual o elemento interno protegido é declarado e deve ocorrer através de uma instância do tipo de classe derivada.

Observe que : protected internalsignifica " protectedOR internal" (qualquer classe na mesma montagem ou qualquer classe derivada - mesmo que esteja em uma montagem diferente).

... e para completar:

privado :

O tipo ou membro pode ser acessado apenas por código na mesma classe ou estrutura.

público :

O tipo ou membro pode ser acessado por qualquer outro código no mesmo assembly ou outro assembly que faça referência a ele.

protegido privado :

O acesso é limitado à classe ou tipos que contêm a classe que contém o conjunto atual.
( Disponível desde C # 7.2 )

M4N
fonte
2
Posso ter um membro protected internalpara que ele esteja protectedna montagem atual e completamente indisponível externamente?
Shimmy Weitzhandler
8
Isso seria "protegido", não seria?
Bloke CAD 25/03/16
2
@ Shimmy: você pode ter uma classe interna com métodos protegidos . Mas então toda a classe estará indisponível em assemblies externos.
M4N 27/03
1
@Shimmy, consulte esta proposta para uma versão futura do C # github.com/dotnet/roslyn/blob/features/privateProtected/docs/…
Nate Cook
@Shimmy Pelo menos, o CLR suporta o conceito de interseção de acessibilidade protegida e interna, mas a linguagem C # não. C # suporta apenas a união dos dois modificadores de acesso.
RBT
89

protected pode ser usado por qualquer subclasse de qualquer montagem.

protected internalé tudo o que protectedé, e também qualquer coisa na mesma montagem pode acessá-lo.

Importante, não significa "subclasses na mesma montagem" - é a união das duas, não a interseção.

Marc Gravell
fonte
3
Apenas uma FYI para os leitores que o CLR também suporta o conceito de interseção de acessibilidade protegida e interna, mas o C # não suporta isso. O C # suporta apenas a união dos dois, conforme mencionado neste post.
RBT
1
Só mais um FYI para os leitores "subclasses no mesmo assembly" pode ser alcançado com o private protectedmodificador de acesso que foi introduzida no C # 7.2
LordWilmore
52

- Atualizar resposta 2019 -

Você pode encontrar a diferença na acessibilidade baseada na tabela abaixo: sim,

insira a descrição da imagem aqui

Andi AR
fonte
4
Bela resposta, comunica muito claramente as diferenças entre cada modificador de acesso.
E_i_pi 26/09/19
23

Na prática, sobre métodos:

protegido - acessível para classes herdadas, caso contrário privado.

interno - público somente para classes dentro da montagem, caso contrário privado.

protegido interno - meios protegido ou internos - métodos tornam acessíveis para classes herdadas e para quaisquer classes dentro do conjunto.

abatishchev
fonte
1
Eu usaria OR para expressar essa causa, ou não é isso que tem que ser verdade.
27611 Brian Rasmussen
Não concordo completamente com a parte "para alterar o comportamento da classe base" na descrição de "protegido". Eu diria que é aqui que você usa "virtual" (na classe base) e "override" (na classe derivada).
M4N
Existe uma maneira de marcar um membro como protectedAND internal?
Shimmy Weitzhandler
@Shimmy: sim protected internal,.
abatishchev
1
@ Shimmy dois anos depois, e sim. Agora existe uma maneira no C # 7.2. É chamado private protected docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
Pauli Østerø 17/17/17 /
10

Ainda há muita confusão na compreensão do escopo dos acessadores "internos protegidos", embora a maioria tenha a definição definida corretamente. Isso me ajudou a entender a confusão entre "protegido" e "protegido interno":

público é realmente público dentro e fora da assembléia ( público interno / público externo )

protected é realmente protegido dentro e fora da montagem ( interno protegido / externo protegido ) (não permitido nas classes de nível superior)

private é realmente privado dentro e fora da montagem ( privado interno / privado externo ) (não permitido nas classes de nível superior)

interno é realmente público dentro da montagem, mas excluído fora da montagem como privado ( público interno / externo excluído )

interno protegido é realmente público dentro da montagem, mas protegido fora da montagem ( público interno / externo protegido ) (não permitido nas classes de nível superior)

Como você pode ver protegido interno é um animal muito estranho. Não é intuitivo.

Isso agora levanta a questão: por que a Microsoft não criou um ( interno protegido / excluído externo ), ou acho que algum tipo de "proteção privada" ou "proteção interna"? ri muito. Parece incompleto?

Adicionado à confusão está o fato de que você pode aninhar membros aninhados internos públicos ou protegidos em tipos protegido, interno ou privado. Por que você acessaria um "interno protegido" aninhado dentro de uma classe interna que exclui o acesso de montagem externo?

A Microsoft diz que esses tipos aninhados são limitados pelo escopo do tipo pai, mas não é isso que o compilador diz. Você pode compilar componentes internos protegidos dentro de classes internas, o que deve limitar o escopo apenas à montagem.

Para mim, isso parece um projeto incompleto. Eles devem ter escopo simplificado de todos os tipos para um sistema que considere claramente a herança, mas também a segurança e a hierarquia dos tipos aninhados. Isso tornaria o compartilhamento de objetos extremamente intuitivo e granular, em vez de descobrir a acessibilidade de tipos e membros com base em um sistema de escopo incompleto.

Stokely
fonte
1
Agora, private protected foi adicionado ao C # 7.2, que é basicamente interno e protegido.
Pauli Østerø 17/11
7

protected : a variável ou método estará disponível apenas para classes filho (em qualquer assembly)

interno protegido : disponível para classes filho em qualquer assembly e para todas as classes dentro do mesmo assembly

Benjamin
fonte
3

Eu li definições muito claras para esses termos.

Protegido: o acesso é limitado à definição da classe e a qualquer classe que herda da classe. O tipo ou membro pode ser acessado apenas por código na mesma classe ou estrutura ou em uma classe derivada dessa classe.

Interno: o acesso é limitado exclusivamente às classes definidas na montagem do projeto atual. O tipo ou membro pode ser acessado apenas por código na mesma classe.

Interno protegido: o acesso é limitado à montagem ou tipos atuais derivados da classe que contém.

Ammar Asjad
fonte
1

Membro Protegido

Membro protegido de uma classe disponível apenas na classe contida (na qual foi declarada) e na classe derivada dentro da montagem e também fora da montagem.

Significa se uma classe que reside fora da montagem pode usar o membro protegido da outra montagem herdando apenas essa classe.

Podemos expor o membro Protegido fora da montagem herdando essa classe e usá-lo somente na classe derivada.

Nota: Os membros protegidos não são acessíveis usando o objeto na classe derivada.

Membro Interno

Membro interno de uma classe está disponível ou acesso dentro da montagem, criando objeto ou em uma classe derivada, ou você pode dizer que é acessível em todas as classes da montagem.

Nota: Membros internos não acessíveis fora da montagem usando a criação de objeto ou em uma classe derivada.

Interno protegido

O modificador de acesso interno protegido é uma combinação protegida ou interna.

Membro Interno Protegido pode estar disponível em toda a montagem na qual ele declarou criar objeto ou herdou essa classe. E pode ser acessível fora da montagem apenas em uma classe derivada.

Nota: O membro Interno Protegido funciona como Interno na mesma montagem e funciona como Protegido para fora da montagem.

Mostafa Bouzari
fonte
1

public - Os membros (Funções e Variáveis) declarados como públicos podem ser acessados ​​de qualquer lugar.

privado - Membros privados não podem ser acessados ​​de fora da classe. Este é o especificador de acesso padrão para um membro, ou seja, se você não especificar um especificador de acesso para um membro (variável ou função), ele será considerado privado. Portanto, string PhoneNumber; é equivalente à sequência privada PhoneNumber.

protected - Membros protegidos podem ser acessados ​​apenas a partir das classes filho.

interno - pode ser acessado apenas dentro da mesma montagem.

interno protegido - Pode ser acessado na mesma montagem e na classe derivada.

Piush shukla
fonte
0

Melhores suítes internas protegidas quando você deseja que um membro ou tipo seja usado em uma classe derivada de outra montagem ao mesmo tempo, apenas deseja consumir o membro ou o tipo na montagem pai sem derivar da classe em que é declarada. Além disso, se você deseja usar apenas um membro ou tipo sem derivar de outra classe, na mesma montagem você pode usar apenas interno.

satishpkumarin
fonte