Pregunta

¿Hay buenos usos de las clases parciales fuera de los escenarios de código generado de formularios web / winforms? ¿O es esta característica básicamente para apoyar eso?

¿Fue útil?

Solución

Es en parte para admitir escenarios (WebForms, WinForms, LINQ-to-SQL, etc.) mezclando código generado con código de programador.

Hay más razones para usarlo. Por ejemplo, si tiene clases grandes en archivos grandes y difíciles de manejar, pero las clases tienen grupos de métodos relacionados lógicamente, las clases parciales pueden ser una opción para hacer que los tamaños de los archivos sean más manejables.

Otros consejos

La generación de código fue la fuerza impulsora detrás de las clases parciales. La necesidad proviene de tener una clase generada por código que cambia constantemente, pero permite a los desarrolladores suministrar código personalizado como parte de la clase que no se anulará cada vez que se realicen cambios que obliguen a la clase a regenerarse.

Tomemos, por ejemplo, WinForms o Typed-DataSets (o cualquier diseñador). Cada vez que realiza un cambio en el diseñador, serializa el código correspondiente a un archivo. Digamos que necesita proporcionar algunos métodos adicionales sobre los que el generador no sabe nada. Si lo agrega al archivo generado, sus cambios se perderán la próxima vez que se generen.

Un proyecto en el que estoy trabajando actualmente utiliza la generación de código para todas las entidades comerciales y DAL, BLL. Sin embargo, el generador solo nos da el 75% de la información. La parte restante debe estar codificada a mano (por ejemplo, lógica empresarial personalizada). Puedo asumir que cada clase BLL tiene un método SelectAll, por lo que es fácil de generar. Sin embargo, mi cliente BLL también necesita tener un método SelectAllByLocation. No puedo poner esto en mi generador porque no es genérico para todas las clases de BLL. Por lo tanto, genero todas mis clases como clases parciales y luego, en un archivo separado, defino mis métodos personalizados. Ahora, cuando mi estructura cambie, o si necesito volver a generar mi BLL por alguna razón, mi código personalizado no se borrará.

Utilizo clases parciales para separar los diferentes subelementos de los controles personalizados que escribo. Además, cuando se utiliza con el software de creación de entidades, permite que productos como LLBLGen creen versiones generadas de clases, así como una versión personalizada, editada por el usuario, que no será reemplazada si las entidades necesitan ser regeneradas.

A menudo utilizo clases parciales para dar a cada clase anidada su propio archivo. Ha habido algunas arquitecturas en las que he trabajado donde la mayor parte de la implementación solo fue requerida por una clase, por lo que anidamos esas clases en esa clase. Tenía sentido mantener los archivos más fáciles de mantener utilizando la capacidad de clase parcial y dividiendo cada uno en su propio archivo.

También los hemos utilizado para agrupar anulaciones de acciones o para ocultar un conjunto de propiedades de acciones. Ese tipo de cosas. Es una forma práctica de mezclar un cambio de existencias (solo copie el archivo y cambie el nombre de clase parcial a la clase objetivo, siempre que la clase objetivo también sea parcial, por supuesto).

Otro posible uso para las clases parciales sería aprovechar los métodos parciales para hacer que los métodos desaparezcan selectivamente utilizando la compilación condicional; esto sería excelente para el código de diagnóstico en modo de depuración o los escenarios de pruebas de unidades especializadas.

Puede declarar una clase de método parcial como un método abstracto, y luego en la otra clase parcial, cuando escribe la palabra clave " parcial " puede aprovechar Intellisense para crear la implementación de ese método.

Si rodea una parte con sentencias de compilación condicionales, puede cortar fácilmente el código de prueba o solo de depuración. En el ejemplo a continuación, en modo DEPURACIÓN, se llama al método LogSomethingDebugOnly, pero en la versión de lanzamiento, es como si el método no existiera en absoluto: una buena forma de mantener el código de diagnóstico alejado del código de producción sin un montón de ramificaciones o múltiples bloques de compilación condicional.

// Main Part
public partial class Class1
{
    private partial void LogSomethingDebugOnly();

    public void SomeMethod()
    {
        LogSomethingDebugOnly();
        // do the real work
    }
}

// Debug Part - probably in a different file
public partial class Class1
{

    #if DEBUG

    private partial void LogSomethingDebugOnly()
    {
        // Do the logging or diagnostic work
    }

    #endif
}

LINQ to SQL hace un buen uso de clases parciales para extender el código generado por el diseñador. Creo que normalmente encontrará este patrón de clases parciales que utiliza el código creado por el diseñador.

Me parece que las clases parciales son extremadamente útiles. Normalmente se utilizan para poder extender clases autogeneradas. Los utilicé en un proyecto con pruebas de unidades pesadas. Mis clases de UT tenían dependencias complejas y no era muy práctico separar el código en varias clases. Por supuesto, es mejor usar herencia \ composición, pero en algunos casos las clases parciales pueden ser muy útiles.

Como se mencionó anteriormente, también creo que es un olor a código.

Si una clase es tan grande que necesita dividirse en más archivos, significa que está rompiendo el principio de responsabilidad única y haciendo demasiadas cosas. La clase grande podría dividirse en clases más pequeñas que cooperan juntas.

Si tiene que usar clases o regiones parciales para organizar el código, considere si deberían estar en sus propias clases. Aumenta la legibilidad y obtendrá más reutilización de código.

quizás sea demasiado tarde, pero por favor, permítame agregar mis 2 centavos también:

*. Cuando se trabaja en proyectos grandes, la distribución de una clase en archivos separados permite que varios programadores trabajen en él simultáneamente.

*. Puede escribir fácilmente su código (para funcionalidad extendida) para una clase generada por VS.NET. Esto le permitirá escribir el código de su propia necesidad sin alterar el código generado por el sistema

Donde estoy tenemos un programa que maneja los archivos entrantes de los clientes. Está configurado de modo que el código de cada cliente se encuentre en su propio proyecto de biblioteca de clases, que sabe cómo manejar cualquier formato que el cliente elija usar.

El código principal usa las bibliotecas definiendo una interfaz bastante extensa que una clase en la biblioteca debe implementar (probablemente debería haber algunas interfaces distintas, pero es demasiado tarde para cambiarla ahora). A veces eso implica mucho más código en la misma clase de lo que normalmente pensaríamos prudente. Las clases parciales nos permiten dividirlas un poco.

En UserControls, que son relativamente complicados, coloco las cosas de manejo de eventos en un archivo y la pintura y las propiedades en otro archivo. Las clases parciales funcionan muy bien para esto, por lo general, estas partes de la clase son relativamente independientes y es bueno poder editar la pintura y el manejo de eventos en paralelo.

Hace un par de años trabajé en un proyecto en el que teníamos una clase DataSet con un montón de código: Métodos en las Tablas de datos, métodos en los Adaptadores de tabla, declaraciones de instancias del Adaptador de tabla, lo que sea. Era un punto central masivo del proyecto en el que todos tenían que trabajar a menudo, y había mucha controversia de control de fuente sobre el archivo de código de clase parcial.

Así que dividí el archivo de código en arreglos o seis archivos de clase parciales, agrupados por función, para que pudiéramos trabajar en piezas más pequeñas y no tener que bloquear todo el archivo cada vez que teníamos que cambiar algo.

(Por supuesto, también podríamos haber resuelto el problema al no usar un sistema de control de código fuente con bloqueo exclusivo, pero ese es otro problema).

Generalmente, lo considero un olor a código.

Si su clase es tan complicada, entonces probablemente se pueda dividir en componentes reutilizables más pequeños.

O significa que no hay una jerarquía de herencia donde debería haber una.

Para los escenarios de generación de código es bueno, pero creo que la generación de código es otro olor de código.

Estoy atrasado en el juego ... pero solo mis 2 centavos ...

Un uso podría ser refactorizar una clase de dios existente en una base de código heredado existente a múltiples clases parciales. Podría mejorar la capacidad de descubrimiento del código, si se sigue la convención de nomenclatura adecuada para los nombres de archivo que contienen las clases parciales. Esto también podría reducir el repositorio de código fuente, resolver y fusionar hasta cierto punto.

Idealmente, una clase divina debería dividirse en varias clases pequeñas, cada una de las cuales tiene una responsabilidad única. A veces es perjudicial realizar refactorizaciones de medianas a grandes. En tales casos, las clases parciales podrían proporcionar un alivio temporal.

Corrección, como Matt señaló, ambos lados del parcial deben estar en el mismo ensamblaje. mi mal.

Lo uso en una capa de acceso a datos. Las clases generadas como el mapeador y las consultas son parciales. Si necesito agregar un método de mapeador, por ejemplo, para hacer una carga elegante que no se genera, lo agrego a la clase personalizada.

Al final, el programador que usa la capa de datos en la capa empresarial solo ve una clase con toda la funcionalidad que necesita. Y si la fuente de datos cambia, las partes genéricas se pueden generar fácilmente sin sobrescribir las cosas personalizadas.

Acabo de encontrar un uso para clases parciales. Tengo una clase [DataContract] que uso para pasar datos al cliente. Quería que el cliente pudiera mostrar la clase de una manera específica (salida de texto). así que creé una clase parcial y anulé el método ToString.

A veces puede encontrar código terriblemente antiguo en el trabajo que puede hacer que sea casi imposible refactorizar en elementos distintos sin romper el código existente.

Cuando no se le da la opción o el tiempo para crear una arquitectura más genuina, las clases parciales hacen que sea increíblemente fácil separar la lógica donde sea necesario. Esto permite que el código existente continúe usando la misma arquitectura mientras se acerca un paso más a una arquitectura más concreta.

En cualquier lugar donde hubiera usado las secciones #region antes, probablemente tenga más sentido como archivos separados en clases parciales.

Personalmente uso clases parciales para clases grandes donde los miembros estáticos van en un archivo y los miembros de la instancia en el otro.

EDIT: DSL Tools para Visual Studio usa clases parciales.

Por lo tanto, es una característica que utilizan muchos códigos generados automáticamente. En lugar de usar #region, el código generado automáticamente va a un archivo y el código de usuario (también llamado código personalizado) va a otro e incluso en directorios diferentes para que el desarrollador no se confunda con tantos archivos sin sentido.

Es bueno tener esta opción que puede combinar, pero no forzar a usar, con herencia

Además, puede ser útil separar la lógica de algunas clases entre varios directorios. Por supuesto, para las máquinas, es lo mismo, pero mejora la experiencia de legibilidad del usuario.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top