¿Por qué usar clases parciales?

72

En mi opinión, la palabra clave partial no hace nada, pero permite que una clase se divida entre varios archivos de origen. ¿Hay alguna razón para hacer esto con excepción de la organización del código? Lo he visto usado para eso en las clases de UI generadas.

Parece una mala razón para crear una palabra clave completa. Si una clase es lo suficientemente grande como para requerir múltiples archivos, probablemente esté haciendo demasiado. Pensé que tal vez podrías usarlo para definir parcialmente una clase para que la complete otro programador, pero sería mejor hacer una clase abstracta.

    
pregunta Michael K 26.04.2011 - 21:42

9 respuestas

110

Es muy útil en todos los escenarios donde una herramienta personalizada genera una parte de la clase porque le permite agregar lógica personalizada al código generado sin heredar la clase generada. Por cierto También hay métodos parciales por la misma razón.

No solo se trata de IU, sino que otras tecnologías, como Linq-To-Sql o Entity Framework, lo utilizan mucho.

    
respondido por el Ladislav Mrnka 26.04.2011 - 21:44
25

Como usted dice, a menudo se usa para separar el código generado. A menudo no tiene nada que ver con el tamaño de las clases / archivos.

El beneficio de separar el código generado es uno de estilo. El código generado puede ser bastante feo e ilegible y fallaría en muchos estándares de codificación (y cheques de StyleCop), pero está bien, nadie tiene que leerlo o mantenerlo directamente. Por lo tanto, si lo "esconde" en otro archivo, puede concentrarse en asegurarse de que el resto de la clase sea estándar, pase las comprobaciones de StyleCop, etc.

Otra área donde lo he usado es donde una clase implementa múltiples interfaces, puede ser bastante bueno separar la implementación en archivos separados, aunque esto es más una cuestión de preferencia personal, nunca he visto ningún código los estándares requieren (o previenen) esto.

    
respondido por el Steve Haigh 26.04.2011 - 21:51
18

Uno de los desarrolladores en los que trabajo surgió para hacer un buen uso de ellos hace un par de semanas en la refactorización de enormes clases de Dios que se han salido de control y tienen muchos métodos públicos: separando las funciones lógicas de Cada bit de la clase en clases parciales separadas puede separar físicamente la clase en las unidades más atómicas que deberían ser las clases sin romper ninguna funcionalidad existente, lo que le permite ver qué es común y qué no lo es. Con esto como una primera etapa, puede separar más fácilmente los parciales en sus propias clases independientes e implementarlas en todo el código base. Pensé que esto era una buena idea.

Sin embargo, en general, creo que solo deberían usarse para aumentar las clases generadas por la máquina cuando se escribe un nuevo código.

    
respondido por el user23157 26.04.2011 - 21:54
17

Puedo pensar en algunos escenarios útiles donde los parciales tienen sentido, la mayoría de ellos me estoy usando en mis proyectos:

  • Para separar el código generado por Tool / IDE / Designer del código que está manteniendo. Un buen ejemplo es el archivo Form.Designer.cs que contiene el código generado por el diseñador para aplicaciones de formularios de Windows. Muchos otros formatos .NET también tienen algún código generado por la herramienta, que puede ser potencialmente regenerado cuando construyes tu proyecto, y por lo tanto todos tus cambios personalizados serán eliminados. La separación lo ayudará a mantener su código y los cambios a salvo de dichas modificaciones automatizadas.

  • Cuando está implementando múltiples interfaces con una gran cantidad de código en la implementación. Tiendo a usar un archivo parcial separado para cada una de esas interfaces, nombrándolo así: {Class}.{Interface}.cs . Es fácil para mí ver en el IDE qué interfaces implementa {Class} y cómo.

  • Cuando la clase debe contener una o más clases anidadas , especialmente con suficiente código en ellas para colocarlas en un archivo separado. Me apegaría al patrón anterior y usaría la convención de denominación {Class}.{NestedClass}.cs para cada clase anidada. La práctica similar ya se menciona en respuesta de Virtlink .

  • Cuando escribo static clases que contendrán métodos de extensión . A menudo será el caso proporcionar la misma lógica de método de extensión a clases o interfaces similares, como por ejemplo Reverse en colecciones genéricas y no genéricas. Pondría todos los métodos de extensión para una sola clase o interfaz en un parcial separado de la clase estática. Por ejemplo, tendría todos los métodos de extensión para la interfaz IList en un lugar, y los mismos métodos que son para IList<T> en otro archivo. Otro enfoque sería poner el mismo método (todas sus sobrecargas) en el mismo parcial, con todas las clases posibles para el parámetro this , como tener todas las implementaciones Reverse en un archivo. Depende de cuál de ellas justificaría mejor la separación en términos de volumen de código, o algunas convenciones internas a las que usted o su organización podrían adherirse.

  • No uso esto, pero he visto a algunas personas de C / C ++ que les gusta el enfoque que describiré aquí: crear un parcial para la clase con métodos parciales solamente. Esto se asemeja a la forma C / C ++ de definir interfaces y separar la declaración del método de la implementación.

  • Separación por simplemente problemas lógicos . Si por casualidad trabaja con una clase grande que combina más de un conjunto lógico de operaciones en sí mismo, entonces podría separar cada código relacionado lógicamente en un parcial separado. Por lo general, la existencia de tales clases va en contra del principio de separación de preocupaciones , pero a menudo se observa en casos reales, especialmente en las bases de código más antiguas. El usuario Steve Evers los mencionó en su respuesta a esta pregunta , refiriéndose a ellos con el nombre objetos de dios . Personalmente, uso el enfoque de clases parciales para dividir el código antes de que se realice una refactorización de archivos realmente grandes, a fin de facilitar mi trabajo y hacer que la refactorización sea más transparente. Esto también reducirá los conflictos que posiblemente cause cuando se involucren sistemas de versiones como SVN.

respondido por el Ivaylo Slavov 01.04.2014 - 13:28
14

No lo he visto mencionado por nadie: uso partial para poner clases anidadas en sus propios archivos.

Todos mis archivos de código contienen solo una clase, estructura, interfaz o enumeración. Hace que sea mucho más fácil encontrar la definición de un objeto cuando los nombres de los archivos muestran el nombre de lo que está buscando. Y dado que Visual Studio intenta hacer coincidir las carpetas del proyecto con los espacios de nombres, los nombres de archivo deben coincidir con las clases.

Esto también significa que una clase NestedClass anidada dentro de MyClass tendrá su propio archivo en mis proyectos: MyClass.NestedClass.cs .

partial class MyClass
{
    private class NestedClass
    {
        // ...
    }
}
    
respondido por el Daniel Pelsmaeker 06.02.2013 - 21:07
10

Con la excepción de usar el código generado, solo he visto haberlos usado en un esfuerzo por cubrir dios objetos . Tratar de comprender un nuevo código base o navegar a través de múltiples archivos de origen, que son el mismo objeto, es muy molesto.

Entonces, cuando preguntas a Why use partial classes? , respondo: a menos que estés usando el código generado, no.

    
respondido por el Steven Evers 26.04.2011 - 22:42
6

La organización del código es la única razón, pero va más allá de lo que parece a primera vista. Si tiene clases parciales donde se generan partes, puede fácilmente:

  • Regenere el código sin tener que detectar cambios manuales en las clases en las que escribe (para no sobrescribir esas partes).
  • Excluya las clases parciales generadas de la cobertura de prueba, control de fuente, métricas, etc.
  • Use el código generado sin obligarlo a basar su estrategia de herencia a su alrededor (todavía puede heredar de otras clases).
respondido por el Deckard 26.04.2011 - 21:58
1

También hay algunos lugares donde las clases generadas / implícitas se declaran parciales, por lo que si el Dev necesita ampliarlas, tienen acceso completo sin tener que meterse en la herencia y la anulación en todo el lugar. Mire las clases generadas en el área temporal de asp.net después de ejecutar un sitio de formularios web por primera vez en IIS si desea intentar capturar algunos ejemplos.

    
respondido por el Bill 26.04.2011 - 22:43
1

Puedo pensar en un uso sucio para ellos.

Suponga que tiene algunas clases que necesitan una funcionalidad común, pero no desea inyectar esa funcionalidad en la cadena de herencia que se encuentra sobre ellas. O bien, tiene un conjunto de clases que utilizan una clase auxiliar común.

Básicamente, quieres hacer herencia múltiple pero no C # no es así. Entonces, lo que haces es usar parcial para crear lo que es esencialmente un #include en C / C ++;

Coloque toda la funcionalidad en una clase, o use la clase auxiliar. Luego copie el ayudante X veces y renómbrelo como clase parcial A, B, C. y ponga parcial en sus clases A, B, C.

Descargo de responsabilidad: Sí, esto es malo. Nunca lo hagas, especialmente si va a hacer que otras personas se enojen contigo.

    
respondido por el Mark 13.07.2011 - 09:37

Lea otras preguntas en las etiquetas