Una clase por regla de archivo en .NET?

Sigo esta regla, pero algunos de mis colegas no están de acuerdo con ella y argumentan que si una clase es más pequeña, se puede dejar en el mismo archivo con otra (s) clase (s).

Otro argumento que escucho todo el tiempo es “Incluso Microsoft no hace esto, entonces ¿por qué deberíamos hacerlo?”

¿Cuál es el consenso general sobre esto? ¿Hay casos en que esto debería evitarse?

Una clase por archivo también le da una mejor idea de lo que cada control está cambiando sin mirar las diferencias del archivo.

Odio cuando la gente piensa en términos absolutos y dice que nunca debes hacer esto o aquello con algo subjetivo y quisquilloso como este, como si todos tuviéramos que conformarnos con la estúpida idea de lo correcto o incorrecto. En pocas palabras: tener más de una clase por archivo está totalmente bien si tiene sentido. Por sentido, me refiero a cosas como:

  1. Hace que el código sea más fácil de digerir y mantener
  2. Hace que la solución sea menos molesta (se desplaza por innumerables archivos innecesarios) y menos lenta
  3. El equipo de desarrollo está de acuerdo con esto como una práctica de encoding local

Un muy buen ejemplo de por qué puedo querer múltiples clases por archivo:

Digamos que tengo unas pocas docenas de clases de excepción personalizadas, cada una es un trazador de líneas 4, podría tener un archivo separado para cada una o podría agrupar las excepciones y tener un archivo por grupo. Para mí, lo que parece ser el enfoque más racional / pragmático es agruparlos, y solo tener algunos archivos, porque es más eficiente en tiempo / encoding (no tengo que hacer clic derecho -> Agregar clase, renombrar, 50 veces) , mantiene la solución menos desordenada y de mejor rendimiento.

static bool GeneralRuleShouldBeFollowed(IGeneralRule rule, IUseCase useCase) { return (rule.Overhead(useCase) < My.PersonalThresholds.ConformismVsPracticality); } 

A veces agrupo más de una clase dentro de un archivo si están estrechamente vinculadas y al menos una de ellas es muy pequeña.

La “mejor práctica” general es tener un archivo por clase.

Más allá de argumentos hipotéticos y de enfocarse en Windows .NET con Visual Studio IDE y proyectos de software en crecimiento, tiene sentido en este contexto tener una clase por archivo.


En general, para referencia visual, nada mejor que una clase por archivo. De Verdad.

No sé si Microsoft hace o no lo mismo, sin embargo crearon la palabra clave partial para dividir una clase en varios archivos (esto es aún más grave). A menudo se usa para dividir el código del diseñador generado automáticamente de su código personalizado en la misma clase (pero a veces se usa para permitir que diferentes desarrolladores trabajen en la clase al mismo tiempo a través de diferentes archivos). De modo que Microsoft ve los beneficios de múltiples archivos y todos tienen en mente múltiples ideas de organización de archivos con .NET.

Para las clases anidadas no tiene más remedio que usar un archivo, o al menos las primeras partes de las clases en ellos. Un archivo es necesario y está bien en este caso:

 class BicycleWheel { class WheelSpoke { } } 

De lo contrario, ¿por qué mantendría múltiples clases en un archivo? El argumento “porque son pequeños” o están asociados entre sí no contiene mucha agua porque eventualmente tus clases se asociarán con otras clases. En última instancia, no puede inferir fácilmente la organización interna de los objetos en función de su uso, especialmente a medida que el software continúa creciendo.

Además, si usa carpetas para espacios de nombres , nunca tendrá un conflicto de nombre de clase. También es conveniente ubicar una clase por nombre de archivo en el sistema de archivos cuando no está dentro de un entorno de desarrollo como Visual Studio (por ejemplo, si desea editar rápidamente una clase con el Bloc de notas o algo rápido / ligero ).

Muchas buenas razones …

En la gran mayoría de los casos, sigo la regla de una clase por archivo. La única excepción que hago regularmente es la definición de una enumeración estrechamente vinculada a una clase específica. En ese caso, con frecuencia incluiré la definición de la enumeración en el archivo de esa clase.

Yo también creo que debería haber un tipo incluido en un solo archivo.

Hay una excepción a esta regla que debe mencionarse: Tener dos clases que difieren solo por un argumento genérico como:

 RelayCommand 

y

 RelayCommand 

Realmente, esto se reduce a las preferencias personales. Todo el mundo dirá “una clase por archivo”, pero todos tenemos nuestros motivos para evitarlo en determinadas circunstancias. Solía ​​tener un gran proyecto que tenía alrededor de 300 enums diferentes. De ninguna manera voy a tener 300 archivos separados, uno para cada clase, cuando algunas de las enumeraciones solo eran tri-estatales.

Además, para las personas que no pueden encontrar ciertas clases si no están todas en los archivos con el nombre de lo que son, ¿hay alguna razón por la que no utilice la opción Buscar buscando en toda la solución? Utilizar Buscar me ahorra un tiempo valioso para desplazarme por Solution Explorer.

En soluciones más grandes, creo que es muy valioso tener una clase por archivo y que el nombre del archivo sea el mismo que el de la clase. Hace que sea mucho más fácil localizar el código que necesita para trabajar.

La herramienta StyleCop para C # tiene reglas estándar que no requieren más de una clase de nivel superior en un espacio de nombres (más cualquier número de interfaces, delegates y enumeraciones en ese espacio de nombres).

En los casos de dos o más clases en las que la primera y las siguientes clases solo las usa la primera, esas pueden y deben ser clases internas, visibles solo para la clase consumidora.

Encuentro que agrupar una clase con su clase de fábrica estándar en el mismo archivo es muy útil.

Normalmente tendría una clase por archivo, pero normalmente tendría que usar su discreción para ver si el archivo podría contener clases relacionadas, por ejemplo, agrupar sus excepciones que usted mismo y otros desarrolladores pueden reutilizar. En este caso, el usuario solo necesita un archivo para ser incluido en lugar de múltiples archivos.

Entonces, el punto es: ¡se debe usar discreción !

No importa cuán ligero sea el contenido, creo que una clase / interfaz / etc. por archivo es esencial.

Si estoy trabajando en una gran solución en Visual Studio, quiero poder ver los archivos y no tener que profundizar para ver. Incluso con herramientas de navegación como ReSharper, quiero un mapeo 1: 1.

Si encuentra muchos archivos fuente con poco o ningún contenido (tal vez ampliando una clase pero sin agregarle nada), entonces tal vez debería reconsiderar su diseño.

Alguna vez una clase por archivo, pero

Cuando varias clases están estrictamente relacionadas, más de una clase en el mismo archivo fuente es, en mi humilde opinión, MEJOR que dedicar un archivo de código fuente corto a cada clase. La fuente es más legible y compacta (y con #region la misma fuente puede ser más estructurada que antes).

Considere también que a veces es NECESARIO distribuir la misma clase entre diferentes archivos (usando parcial ), ya que tener un archivo fuente de más de 20000 líneas no es útil incluso con la RAM que tengo disponible (pero esta es otra pregunta).

En ocasiones voy a dejar una clase pequeña con una clase más grande, pero solo si están estrechamente relacionados como un objeto y su clase de colección o fábrica.

Sin embargo, hay un problema con esto. Eventualmente la clase pequeña crece hasta el punto en que debería estar en su propio archivo, si lo mueve al nuevo archivo pierde fácil acceso a su historial de revisiones.

es decir.

  • el lunes hago un cambio en mis clases xey en el archivo y.css
  • el martes separe la clase x en su propio archivo x.css porque ha crecido a gran tamaño
  • el miércoles mi jefe quiere ver lo que cambié en la clase x el lunes, así que mira el historial de x.css, solo x.css no muestra el historial antes de los cambios de martes.

¿Es eso realmente un problema? 🙂
Las clases realmente pequeñas, al igual que las enumeraciones, se pueden juntar con otras. Hay una regla a seguir: armar solo las clases que tienen algo en común.

Como digresión, en uno de mis proyectos tengo un archivo que tiene 150 clases dentro. El archivo tiene 10000 líneas de código. Pero se genera automáticamente, por lo que es totalmente aceptable 🙂

Una razón para colocar múltiples clases relacionadas en un solo archivo es para que el pobre bastardo que usa tu API no tenga que pasar medio día escribiendo la statement de importación y el pobre bastardo que tiene que mantener el código no tenga que gastar la mitad un día desplazándose a través del texto estándar de la statement de importación. Mi regla general es que varias clases pertenecen al mismo archivo si casi siempre usas un gran subconjunto de ellas al mismo tiempo en lugar de solo una a la vez.

Hago esto, pero solo cuando las clases están relacionadas en una modalidad padre-hijo y las clases hijo ÚNICAMENTE las usa el padre.

Otro voto para una clase por archivo con el nombre del archivo igual a la clase. Para mí, ayuda con la mantenibilidad a largo plazo. Puedo buscar fácilmente en el repository y ver qué clases son parte de una solución sin tener que abrir el proyecto ni ninguno de los archivos.

Lo sigo el 99% del tiempo. Es bueno seguir los estándares, pero también creo que la flexibilidad tiene su lugar. A veces parece una tonta pérdida de tiempo separar las cosas. En esos momentos, me olvido de mí y solo escribo mi código.

Las respuestas hasta ahora parecen girar en torno a las excepciones de las personas a la regla, así que aquí está el mío: mantengo las clases y sus clases de ‘amigos’ de metadatos juntas cuando uso el paquete DataAnnotations en .NET3.5 SP1. De lo contrario, siempre están en archivos separados. Ya sabes, la mayoría de las veces. Excepto cuando no lo son

Solo hago esto raramente. Por ejemplo, si hay una enumeración o estructura que está estrechamente relacionada con la clase pero demasiado trivial para separarse por sí misma.

O una clase separada para contener algunos métodos de extensión para esa clase principal.

One case could be: cuando sus clases conjuntamente forman un module / unit que sirve algunas clases principales como helper classes , otras no .

eche un vistazo al código fuente del proyecto ASP.NET MVC 2.0 . Sigue estrictamente esta regla

Usualmente me quedo con una clase por archivo. Pero haré excepciones para grupos de construcciones similares que se utilizan en todo el proyecto. Por ejemplo:

  • Un EventArgs.cs que contiene cualquier subclase de EventArgs , ya que por lo general son solo 5-10 líneas de código cada una, pero generalmente son utilizadas por varias clases diferentes. Alternativamente, podría poner las clases EventArgs en el mismo archivo que la clase que declara los eventos.
  • Un Delegates.cs que contiene Delegados que se utilizan a lo largo del proyecto, ya que generalmente son de solo 1 línea cada uno. Nuevamente, la alternativa es ponerlos en el mismo archivo con la clase que los expone / consume.
  • Un Enums.cs que contiene enum s utilizado durante todo el proyecto. (Si hay una enum que solo usa una clase, por lo general la convertiré en private para esa clase).

Me gusta la idea de crear clases más pequeñas y asegurarme de que la clase haga solo lo que se supone que debe hacer. Si tiene varias clases que contribuyen a resolver un solo problema, entonces no hay ningún problema al juntarlas en el mismo archivo.

¡No seguiría las prácticas de MS ya que no son las MEJORES PRÁCTICAS!

El vaivén ha sido muy interesante, y aparentemente no concluyente, aunque mi impresión general es que un mapeo 1-1 entre clases y archivos es la opinión mayoritaria, aunque con algunas excepciones persona por persona.

Tengo curiosidad por saber si alguna de tus respuestas varía dependiendo de si estás: (1) desarrollando una aplicación de Windows Forms, una aplicación web, una biblioteca o lo que sea; o (2) usando Visual Studio o no. Al usar VS, parecería que la regla de una clase por archivo también implicaría una clase por proyecto de VS ya que el consenso en otros hilos parece ser que las soluciones / proyectos de VS deben reflejarse en el directorio / nombre de archivo y estructura. De hecho, mi impresión es que el consenso es tener el nombre de proyecto = nombre de ensamblado = (nested) nombre de espacio de nombres, todo lo cual se reflejaría en el directorio / nombre de archivo y estructura. Si esas son las pautas (o reglas) correctas, entonces todos estos mecanismos de organización aparentemente ortogonales se mantendrían sin embargo sincronizados.

Sí, por el bien de la legibilidad, ¡deberíamos tener un archivo por clase! Acabo de saltar a un proyecto. Veo muchas clases en un archivo. simplemente hace que sea tan difícil para un chico nuevo entenderlo. ¿No deberíamos pensar en la mantenibilidad? cuando desarrollamos un software? muchas veces el desarrollo continuará por otros desarrolladores. Tenemos espacios de nombres para organizar nuestras cosas, ¡no necesitamos archivos para hacer eso !.

Un elemento de código por archivo, sí.

Todo lo demás es una negligencia, y, francamente, un signo de víctima de RAD.

Tan pronto como uno comienza el desarrollo adecuado del software (IoC, patrones de diseño, DDD, TDD, etc.) y deja el “Dios mío, deje esto hecho, no tengo idea de cómo, pero me pagan” en el patio de recreo, uno verá que esta regla realmente importa.