Os tipos de aninhamento são considerados uma má prática?

8

Conforme observado pelo título, os tipos de aninhamento (por exemplo, tipos ou estruturas enumerados em uma classe) são considerados uma má prática ou não? Quando você executa a Análise de Código no Visual Studio, ele retorna a seguinte mensagem, indicando que é:

Aviso 34 CA1034: Microsoft.Design: Não aninhe o tipo 'ClassName.StructueName'. Como alternativa, altere sua acessibilidade para que não fique visível externamente.

No entanto, quando sigo a recomendação da Análise de código, percebo que tendem a existir muitas estruturas e tipos enumerados flutuando no aplicativo que podem ser aplicados apenas a uma única classe ou que só seriam usados ​​com essa classe. Como tal, seria apropriado aninhar o tipo sin nesse caso, ou existe uma maneira melhor de fazê-lo?

rjzii
fonte
Esta questão está intimamente relacionada com programmers.stackexchange.com/questions/34067 estou indeciso sobre se para fechar esta como uma duplicata ...
Walter
@ Walter - Eles estão próximos, mas eu ouvi a pergunta levantada separadamente para aninhar classes em classes e aninhar todos os outros tipos em classes separadamente, para que não machucasse. Acontece que não encontrei essa pergunta quando fiz minha pesquisa originalmente.
rjzii

Respostas:

15

Tipos aninhados não são ruins. O aviso que você está recebendo não está sugerindo que você nunca tenha um tipo aninhado. Simplesmente indica que seu tipo aninhado deve usar um modificador de acesso apropriado e um local de código.

Se o tipo aninhado for realmente usado apenas dentro da classe que contém (ou seja, é um contêiner de dados interno ou um indicador de status), defina seu modificador de acesso como privado.

Se o tipo aninhado fizer parte de uma ou mais assinaturas de método, ele não será realmente local para a classe que o contém. Representa uma mensagem sendo passada para ou de instâncias da classe que o contém. Nesse caso, é discutivelmente melhor mover o tipo aninhado para fora da classe que contém e oferecer um modificador de acesso mais aberto, como interno ou público.

Em suma, o aviso parece recomendar que você torne os tipos locais privados, e os tipos compartilhados devem ficar sozinhos.

JeremyDWill
fonte
O modificador interno é o que tenho feito na maioria dos casos, limpa um pouco as coisas, mas existem muitos deles flutuando no aplicativo.
rjzii
1

Se for usado exclusivamente por essa classe, deve ser tornado privado e é exatamente isso que a mensagem está sugerindo.

Otávio Décio
fonte
Em alguns casos, isso é feito, mas em outros casos, um tipo enumerado está sendo usado em chamadas de método anexadas à classe. Da mesma forma, também vi estruturas sendo usadas para a classe de método se o número de parâmetros exceder um determinado número.
rjzii
0

O aviso sobre tipos de aninhamento foi uma das primeiras "sugestões" que recebi algum tempo depois de ativar a Análise de Código. Foi também a razão pela qual eu o desliguei.

Algumas sugestões são realmente estrangeiras como se viessem de outro planeta.

Coloco enumeração dentro de classes para manter as coisas logicamente unidas.

Pense da seguinte maneira: se os tipos de aninhamento seriam um mal absoluto em todos os casos, por que os projetistas de linguagem o implementariam em primeiro lugar? Como é útil em muitos casos e, a esse respeito, o aviso mencionado é apenas um indicativo de que algo no seu código pode não ser o ideal. Se ele se aplica ou não, cabe a você decidir.


fonte
2
Um espaço para nome deve ser seu agrupamento lógico para a enumeração; não é a classe
Aaron McIver
1
Bem, em algumas situações, acho inconveniente.
Se você está atualmente colocando a enumeração dentro da classe, movê-la para fora da classe para que ela resida dentro do espaço para nome leva todo um CTRL + X associado a um CTRL + V ... não sabe ao certo como isso seria inconveniente?
Aaron McIver 11/01
Às vezes, coloco minhas enums nas aulas. Eu acho que existem razões legítimas para isso - não é uma regra estrita.
Ninguém
3
@rmx Eu nunca usei um enum dentro de uma única classe; ele sempre é usado em várias classes, portanto, defini-lo no espaço para nome como sua própria entidade faz muito mais sentido.
Aaron McIver
0

Não

Um bom exemplo em C # é o IEnumerable, onde outras classes não precisam saber a classe exata que retorna, apenas que é um IEnumerator. Portanto, faz sentido torná-la uma classe aninhada, caso contrário, você pode ter muitas classes pequenas flutuando no intellisense que implementam o IEnumerator

Homde
fonte
Em alguns casos, a eficiência do tempo de execução pode ser aprimorada se um compilador souber o tipo retornado por GetEnumerator(); por esse motivo, List<T>.GetEnumerator()retorna List<T>.Enumerator(). Se houvesse alguma maneira de pedir ao compilador para usar outro método nomeado, talvez fosse melhor ter esse método, por exemplo, ForEachGetEnumerator()return List<T>.Enumeratore GetEnumerator()return IEnumerator<T>, mas não existe nenhum mecanismo para isso.
Supercat