¿Los tipos de anidación se consideran una mala práctica?

8

Como se señala en el título, ¿los tipos de anidación (por ejemplo, tipos o estructuras enumerados en una clase) se consideran una mala práctica o no? Cuando ejecuta Code Analysis en Visual Studio, devuelve el siguiente mensaje que implica que es:

Advertencia 34 CA1034: Microsoft.Design: No anide el tipo 'ClassName.StructueName'. Alternativamente, cambie su accesibilidad para que no sea visible externamente.

Sin embargo, cuando sigo la recomendación del Análisis de código, encuentro que tienden a existir muchas estructuras y tipos enumerados que flotan en la aplicación y que solo pueden aplicarse a una sola clase o solo se usarán con esa clase. Como tal, ¿sería apropiado anidar el tipo sin ese caso, o hay una mejor manera de hacerlo?

rjzii
fuente
Esta pregunta está MUY íntimamente relacionada con programmers.stackexchange.com/questions/34067 No sé si cerrar esto como un duplicado ...
Walter
@Walter: están cerca, pero he escuchado la pregunta por separado para anidar clases en clases y anidar todos los demás tipos en clases por separado, por lo que no podría doler. Como resultado, no encontré esa pregunta cuando hice mi búsqueda originalmente.
rjzii

Respuestas:

15

Los tipos anidados no son malos. La advertencia que está recibiendo no sugiere que nunca tenga un tipo anidado. Simplemente indica que su tipo anidado debe usar un modificador de acceso apropiado y una ubicación de código.

Si el tipo anidado realmente solo se usa dentro de la clase que lo contiene (es decir, es un contenedor de datos interno o un indicador de estado), configure su modificador de acceso en privado.

Si el tipo anidado es parte de una o más firmas de método, de hecho no es local para la clase que lo contiene. Representa un mensaje que se pasa ao desde instancias de la clase que lo contiene. En este caso, podría decirse que es mejor mover el tipo anidado fuera de la clase que lo contiene y darle un modificador de acceso más abierto como interno o público.

En resumen, la advertencia parece estar recomendando que haga que los tipos locales sean privados, y los tipos compartidos deberían ser independientes.

JeremyDWill
fuente
El modificador interno es lo que he estado haciendo en la mayoría de los casos, limpia un poco las cosas, pero hay muchas de ellas flotando en la aplicación.
rjzii
1

Si es utilizado únicamente por esa clase, debe hacerse privado y eso es exactamente lo que sugiere el mensaje.

Otávio Décio
fuente
En algunos casos, se hace, pero en otros casos se utiliza un tipo enumerado en las llamadas a métodos adjuntas a la clase. Del mismo modo, también he visto estructuras que se utilizan para la clase de método si el número de parámetros excede un número dado.
rjzii
0

La advertencia sobre los tipos de anidamiento fue una de las primeras "sugerencias" que recibí hace algún tiempo después de haber habilitado el Análisis de código. También fue la razón por la que lo apagué.

Algunas sugerencias son realmente extrañas como si vinieran de otro planeta.

Pongo enumeración dentro de las clases para mantener las cosas lógicamente juntas.

Piénselo de esta manera: si los tipos de anidamiento hubieran sido absolutamente malvados en todos los casos, ¿por qué los diseñadores de idiomas lo habrían implementado en primer lugar? Debido a que es útil en muchos casos y en ese sentido, dicha advertencia es simplemente una señal de que algo en su código podría no ser óptimo. Si corresponde o no, depende de usted decidir.


fuente
2
Un espacio de nombres debe ser su agrupación lógica para la enumeración; no es la clase
Aaron McIver
1
Bueno, en algunas situaciones me resulta inconveniente.
Si actualmente está colocando la enumeración dentro de la clase, moverla fuera de la clase para que resida dentro del espacio de nombres toma todo un CTRL + X junto con un CTRL + V ... ¿no está seguro de cómo sería inconveniente?
Aaron McIver
A veces pongo mis enumeraciones dentro de las clases. Creo que hay razones legítimas, no es una regla estricta.
Nadie
3
@rmx Nunca he usado una enumeración dentro de una sola clase; siempre se usa dentro de múltiples clases, por lo que definirlo dentro del espacio de nombres como su propia entidad tiene mucho más sentido.
Aaron McIver
0

No

Un buen ejemplo en C # es IEnumerable donde otras clases no necesitan saber la clase exacta que devuelve, solo que es un IEnumerator. Por lo tanto, tiene sentido convertirlo en una clase anidada; de lo contrario, podría tener muchas clases pequeñas flotando en intellisense que implementa IEnumerator

Homde
fuente
En algunos casos, la eficiencia del tiempo de ejecución se puede mejorar si un compilador conoce el tipo devuelto por GetEnumerator(); Por eso, List<T>.GetEnumerator()vuelve List<T>.Enumerator(). Si hubiera sido alguna forma de pedirle al compilador que use algún otro método con nombre, podría haber sido mejor tener ese método, por ejemplo, ForEachGetEnumerator()return List<T>.Enumeratory tener GetEnumerator()return IEnumerator<T>, pero no existe ningún mecanismo para eso.
supercat