¿Cuándo es apropiado usar clases parciales de C #?

Me preguntaba si alguien podría darme una visión general de por qué los usaría y qué ventaja ganaría en el proceso.

El mayor uso de las clases parciales es hacer la vida más fácil para los generadores / diseñadores de códigos. Las clases parciales le permiten al generador simplemente omitir el código que necesitan omitir y no tienen que lidiar con las ediciones del usuario en el archivo. Los usuarios también pueden anotar la clase con nuevos miembros teniendo una segunda clase parcial. Esto proporciona un marco muy limpio para la separación de preocupaciones.

Una mejor manera de verlo es ver cómo funcionaban los diseñadores antes de las clases parciales. El diseñador de WinForms escupiría todo el código dentro de una región con comentarios fuertemente redactados sobre la no modificación del código. Tuvo que insertar todo tipo de heurística para encontrar el código generado para su posterior procesamiento. Ahora puede simplemente abrir el archivo designer.cs y tener un alto grado de seguridad de que contiene solo código relevante para el diseñador.

Otro uso es dividir la implementación de diferentes interfaces, por ejemplo:

partial class MyClass : IF1, IF2, IF3 { // main implementation of MyClass } partial class MyClass { // implementation of IF1 } partial class MyClass { // implementation of IF2 } 

Aparte de las otras respuestas …

Los he encontrado útiles como escalón para refactorizar las clases de Dios. Si una clase tiene múltiples responsabilidades (especialmente si se trata de un archivo de código muy grande), entonces me parece beneficioso agregar 1x responsabilidad por clase parcial como primer paso para organizar y luego refactorizar el código.

Esto ayuda enormemente porque puede ayudar a hacer que el código sea mucho más legible sin afectar el comportamiento de ejecución. También puede ayudar a identificar cuándo una responsabilidad es fácil de refactorizar o está estrechamente relacionada con otros aspectos.

Sin embargo, para ser claros, este sigue siendo un código incorrecto; al final del desarrollo, usted todavía desea una responsabilidad por clase ( NO por clase parcial). Es solo un trampolín 🙂

  1. Desarrollador múltiple que usa clases parciales, varios desarrolladores pueden trabajar fácilmente en la misma clase.
  2. Generador de código Las clases parciales son utilizadas principalmente por el generador de código para mantener distintas preocupaciones por separado
  3. Métodos parciales Usando clases parciales también puede definir métodos parciales donde un desarrollador puede simplemente definir el método y el otro desarrollador puede implementarlo.
  4. Declaración parcial del método solamente Incluso el código se comstack con la statement del método solamente y, si la implementación del método no está presente, el comstackdor puede eliminar de forma segura ese fragmento de código y no se producirá ningún error de tiempo de comstackción.

    Para verificar el punto 4. Simplemente cree un proyecto winform e incluya esta línea después del Constructor Form1 e intente comstackr el código

     partial void Ontest(string s); 

Aquí hay algunos puntos a considerar al implementar clases parciales:

  1. Use palabra clave parcial en cada parte de la clase parcial.
  2. El nombre de cada parte de la clase parcial debe ser el mismo, pero el nombre del archivo de origen para cada parte de la clase parcial puede ser diferente.
  3. Todas las partes de una clase parcial deben estar en el mismo espacio de nombres.
  4. Cada parte de una clase parcial debe estar en el mismo ensamblado o DLL, en otras palabras, no puede crear una clase parcial en los archivos fuente de un proyecto de biblioteca de clase diferente.
  5. Cada parte de una clase parcial debe tener la misma accesibilidad. (es decir: privado, público o protegido)
  6. Si hereda una clase o interfaz en una clase parcial, entonces es heredada por todas las partes de esa clase parcial.
  7. Si se sella una parte de una clase parcial, entonces se sellará toda la clase.
  8. Si una parte de la clase parcial es abstracta, entonces toda la clase se considerará una clase abstracta.

Un gran uso es separar el código generado del código escrito a mano que pertenece a la misma clase.

Por ejemplo, dado que LINQ to SQL usa clases parciales, puede escribir su propia implementación de ciertas piezas de funcionalidad (como las relaciones Muchos a Muchos) y esas piezas de código personalizado no se sobrescribirán cuando vuelva a generar el código.

Lo mismo ocurre con el código de WinForms. Todo el código generado por Designer va en un archivo que generalmente no toca. Su código escrito a mano va en otro archivo. De esta manera, cuando cambias algo en Designer, tus cambios no se desvanecen.

Es cierto que la clase parcial se utiliza en la generación automática de códigos; un uso puede ser mantener un archivo de clase grande que podría tener mil líneas de código. Nunca se sabe que su clase podría terminar con 10 mil líneas y no desea crear una clase nueva con un nombre diferente.

 public partial class Product { // 50 business logic embedded in methods and properties.. } public partial class Product { // another 50 business logic embedded in methods and properties.. } //finally compile with product.class file. 

Otro posible uso podría ser que más de un desarrollador puede trabajar en la misma clase que se almacenan en diferentes lugares. La gente puede reír pero nunca se sabe que puede ser difícil a veces.

Product1.cs

 public partial class Product { //you are writing the business logic for fast moving product } 

Product2.cs

 public partial class Product { // Another developer writing some business logic... } 

Espero que tenga sentido!

mantenga todo lo más limpio posible cuando trabaje con clases grandes, o cuando trabaje en un equipo, puede editar sin anular (o siempre realizando cambios)

Las clases parciales abarcan múltiples archivos.

How can you use the partial modifier on a C# class declaration?

Con parcial, puede separar físicamente una clase en varios archivos.

Esto a menudo lo hacen los generadores de código.

Ejemplo

Con las clases normales de C #, no puede declarar una clase en dos archivos separados en el mismo proyecto.

Pero con el modificador parcial, puedes.

Esto es útil si un archivo se edita comúnmente y el otro se genera en máquina o rara vez se edita.

An Example will clear your concept.

 class Program { static void Main() { A.A1(); A.A2(); } } //Contents of file A1.cs: C# using System; partial class A { public static void A1() { Console.WriteLine("A1"); } } //Contents of file A2.cs: C# using System; partial class A { public static void A2() { Console.WriteLine("A2"); } } Output A1 A2 

Parcial es requerido aquí.

If you remove the partial modifier, you will get an error containing this text: [The namespace '' already contains a definition for 'A'].

Consejo: Para solucionar esto, puede usar la palabra clave parcial o cambiar uno de los nombres de clase.

How does the C# compiler deal with partial classes?

Si desarma el progtwig anterior, verá que se eliminan los archivos A1.cs y A2.cs.

Descubrirá que la clase A está presente.

Desensamblador IL Entonces: la clase A contendrá los métodos A1 y A2 en el mismo bloque de código. Las dos clases se fusionaron en una.

Resultado comstackdo de A1.cs y A2.cs: C #

 internal class A { // Methods public static void A1() { Console.WriteLine("A1"); } public static void A2() { Console.WriteLine("A2"); } } 

Resumen

Las clases parciales pueden simplificar ciertas situaciones de progtwigción de C #.

A menudo se usan en Visual Studio cuando se crean progtwigs Windows Forms / WPF.

El código de C # generado por la máquina está separado.

O puede encontrar toda la Descripción aquí .

El uso principal para las clases parciales es con código generado. Si observa la red WPF (Windows Presentation Foundation), define su UI con marcado (XML). Ese marcado se comstack en clases parciales. Usted completa el código con clases parciales propias.

Si tiene una clase suficientemente grande que no se preste a una refactorización efectiva, separarla en múltiples archivos ayuda a mantener las cosas organizadas.

Por ejemplo, si tiene una base de datos para un sitio que contiene un foro de discusión y un sistema de productos, y no desea crear dos clases de proveedores diferentes (NO es lo mismo que una clase de proxy, solo para ser claro), puede crea una única clase parcial en diferentes archivos, como

MyProvider.cs – lógica del núcleo

MyProvider.Forum.cs – métodos que pertenecen específicamente al foro

MyProvider.Product.cs – métodos para productos

Es solo otra forma de mantener las cosas organizadas.

Además, como han dicho otros, se trata de la única forma de agregar métodos a una clase generada sin correr el riesgo de que sus adiciones se destruyan la próxima vez que se regenere la clase. Esto es útil con código generado por plantilla (T4), ORM, etc.

Otro uso que vi es,

Extendiendo una gran clase abstracta con respecto a la lógica de acceso a datos,

Tengo varios archivos con los nombres Post.cs, Comment.cs, Pages.cs …

 in Post.cs public partial class XMLDAO :BigAbstractClass { // CRUD methods of post.. } in Comment.cs public partial class XMLDAO :BigAbstractClass { // CRUD methods of comment.. } in Pages.cs public partial class XMLDAO :BigAbstractClass { // CRUD methods of Pages.. } 

Las referencias de servicio son otro ejemplo donde las clases parciales son útiles para separar el código generado del código creado por el usuario.

Puede “extender” las clases de servicio sin tener que sobrescribirlas cuando actualiza la referencia del servicio.

Como una alternativa a las directivas del precomstackdor.

Si usas directivas de #IF DEBUG (es decir, #IF DEBUG ), terminas con un código de aspecto retorcido mezclado con tu código de lanzamiento real.

Puede crear una clase parcial separada para contener este código, y envolver toda la clase parcial en una directiva, u omitir que el archivo de código se envíe al comstackdor (efectivamente haciendo lo mismo).

Las clases parciales permiten agregar funcionalidad a un progtwig adecuadamente diseñado simplemente agregando archivos fuente. Por ejemplo, un progtwig de importación de archivos podría diseñarse de modo que se puedan agregar diferentes tipos de archivos conocidos al agregar módulos que los manejen. Por ejemplo, el convertidor principal de tipo de archivo podría incluir una clase pequeña:

  Clase pública parcial zzFileConverterRegistrar
     Registro de eventos (ByVal mainConverter como zzFileConverter)
     Sub registerAll (ByVal mainConverter como zzFileConverter)
         RaiseEvent Register (mainConverter)
     End Sub
 Clase final 

Cada módulo que desea registrar uno o más tipos de convertidores de archivos podría incluir algo como:

 Clase pública parcial zzFileConverterRegistrar
     Private Sub RegisterGif (ByVal mainConverter as zzFileConverter) Handles Me.Register
         mainConverter.RegisterConverter ("GIF", GifConverter.NewFactory))
     End Sub
 Clase final

Tenga en cuenta que la clase de convertidor de archivos principal no está “expuesta”; solo expone una pequeña clase de stub a la que los módulos adicionales pueden engancharse. Existe un ligero riesgo de nombrar conflictos, pero si cada rutina de “registro” del módulo de complementos se nombra de acuerdo con el tipo de archivo con el que trata, probablemente no debería suponer un problema. Uno podría pegar un GUID en el nombre de la subrutina de registro si uno estuviera preocupado por tales cosas.

Editar / Adición Para que quede claro, el propósito de esto es proporcionar un medio por el cual una variedad de clases separadas pueda permitir que un progtwig principal o una clase conozcan sobre ellas. Lo único que hará el convertidor principal de archivos con zzFileConverterRegistrar es crear una instancia de este y llamar al método registerAll que disparará el evento Register. Cualquier módulo que quiera enganchar ese evento puede ejecutar código arbitrario en respuesta a él (esa es la idea general) pero no hay nada que un módulo pueda hacer ampliando incorrectamente la clase zzFileConverterRegistrar que no sea definir un método cuyo nombre coincida con el de otra cosa . Ciertamente sería posible que una extensión escrita incorrectamente rompa otra extensión escrita incorrectamente, pero la solución para eso es que cualquiera que no quiera que su extensión se rompa simplemente la escriba correctamente.

Uno podría, sin usar clases parciales, tener un poco de código en alguna parte dentro de la clase principal de conversión de archivos, que se veía así:

   RegisterConverter ("GIF", GifConvertor.NewFactory)
   RegisterConverter ("BMP", BmpConvertor.NewFactory)
   RegisterConverter ("JPEG", JpegConvertor.NewFactory)

pero agregar otro módulo convertidor requeriría entrar en esa parte del código del convertidor y agregar el nuevo convertidor a la lista. El uso de métodos parciales ya no es necesario; todos los convertidores se incluirán automáticamente.

Las clases parciales recientemente ayudaron con el control de fuente donde múltiples desarrolladores estaban agregando un archivo donde se agregaron nuevos métodos en la misma parte del archivo (automatizados por Resharper).

Estos empujones a git provocaron conflictos de fusión. No encontré ninguna manera de decirle a la herramienta de combinación que tome los nuevos métodos como un bloque de código completo.

Las clases parciales a este respecto permiten a los desarrolladores atenerse a una versión de su archivo, y podemos fusionarlos más tarde a mano.

ejemplo –

  • MainClass.cs – contiene campos, constructor, etc.
  • MainClass1.cs – un nuevo código de desarrolladores a medida que implementan
  • MainClass2.cs: es otra clase de desarrolladores para su nuevo código.

La mayoría de las personas comentan que el partial solo debe usarse para una clase que tenga un archivo de código generado o para interfaces. No estoy de acuerdo, y he aquí por qué.

Por ejemplo, veamos la clase C # System.Math … eso es clase . No intentaría rellenar más de 70 métodos en el mismo archivo de código único. Sería una pesadilla mantener.

Colocar cada método matemático en archivos individuales de clase parcial, y todos los archivos de código en una carpeta Math en el proyecto, sería una organización significativamente más limpia.

Lo mismo podría / sería cierto para muchas otras clases que tienen una gran cantidad de funcionalidades diversas. Por ejemplo, una clase para administrar la API PrivateProfile podría beneficiarse si se divide en un conjunto limpio de archivos de clase parcial en una sola carpeta de proyecto.

Personalmente, también dividí lo que mucha gente llama clases de “ayuda” o “utilidad” en archivos parciales individuales para cada método o grupo funcional de método. Por ejemplo, en un proyecto, la clase de ayudante de cuerdas tiene casi 50 métodos. Eso sería un archivo de código largo e inmanejable incluso utilizando regiones. Es significativamente más fácil mantener el uso de archivos de clases parciales individuales para cada método.

Simplemente tendría cuidado al usar clases parciales y mantener todo el diseño del archivo de código constante en todo el proyecto al hacer esto. Como colocar cualquier enumeración pública de clase y miembros privados de clase en un Common.cs o archivo de nombre similar en la carpeta, en lugar de distribuirlos en los archivos a menos que sean específicos solo del archivo parcial en el que están contenidos.

Tenga en cuenta que cuando divide una clase en archivos separados, también pierde la capacidad de utilizar la barra de división del editor de texto que le permite ver dos secciones diferentes de un archivo actual simultáneamente.

Desde MSDN :

1.En tiempo de comstackción, los atributos de las definiciones de tipo parcial se fusionan. Por ejemplo, considere las siguientes declaraciones:

 [SerializableAttribute] partial class Moon { } [ObsoleteAttribute] partial class Moon { } 

Son equivalentes a las siguientes declaraciones:

 [SerializableAttribute] [ObsoleteAttribute] class Moon { } 

Los siguientes se fusionan de todas las definiciones de tipo parcial:

  • Comentarios XML

  • interfaces

  • atributos de parámetros de tipo genérico

  • atributos de clase

  • miembros

2. Otra cosa, las clases parciales anidadas también pueden ser parciales:

 partial class ClassWithNestedClass { partial class NestedClass { } } partial class ClassWithNestedClass { partial class NestedClass { } } 

Aquí hay una lista de algunas de las ventajas de las clases parciales.

Puede separar el código de diseño de la interfaz de usuario y el código de lógica de negocios para que sea fácil de leer y comprender. Por ejemplo, si está desarrollando una aplicación web con Visual Studio y agrega un nuevo formulario web, hay dos archivos fuente, “aspx.cs” y “aspx.designer.cs”. Estos dos archivos tienen la misma clase con la palabra clave parcial. La clase “.aspx.cs” tiene el código de lógica de negocios, mientras que “aspx.designer.cs” tiene definición de control de interfaz de usuario.

Al trabajar con una fuente generada automáticamente, el código se puede agregar a la clase sin tener que volver a crear el archivo fuente. Por ejemplo, está trabajando con LINQ to SQL y crea un archivo DBML. Ahora, cuando arrastra y suelta una tabla, crea una clase parcial en designer.cs y todas las columnas de la tabla tienen propiedades en la clase. Necesita más columnas en esta tabla para enlazar en la cuadrícula de la UI, pero no desea agregar una nueva columna a la tabla de la base de datos para que pueda crear un archivo fuente separado para esta clase que tenga una nueva propiedad para esa columna y lo hará ser una clase parcial. Entonces, eso afecta el mapeo entre la tabla de la base de datos y la entidad DBML, pero puede obtener fácilmente un campo adicional. Significa que puedes escribir el código por tu cuenta sin jugar con el código generado por el sistema.

Más de un desarrollador puede escribir simultáneamente el código para la clase.

Puede mantener su aplicación mejor compactando clases grandes. Supongamos que tiene una clase que tiene múltiples interfaces para que pueda crear múltiples archivos de origen dependiendo de los implementos de interfaz. Es fácil de entender y mantener una interfaz implementada en la que el archivo fuente tiene una clase parcial.

Cada vez que tengo una clase que contiene una clase anidada de cualquier tamaño / complejidad significativa, marco la clase como partial y coloco la clase anidada en un archivo separado. Designo el archivo que contiene la clase anidada usando la regla: [nombre de clase]. [Nombre de clase anidada] .cs.

El siguiente blog de MSDN explica el uso de clases parciales con clases anidadas para la mantenibilidad: http://blogs.msdn.com/b/marcelolr/archive/2009/04/13/using-partial-classes-with-nested-classes-for- maintainability.aspx

Sé que esta pregunta es muy antigua, pero me gustaría agregar mi opinión sobre las clases parciales.

Una razón por la que personalmente uso clases parciales es cuando estoy creando enlaces para un progtwig, especialmente máquinas de estado.

Por ejemplo, OpenGL es una máquina de estados, hay montones de métodos que pueden cambiarse globalmente, sin embargo, en mi experiencia vinculando algo similar a OpenGL donde hay tantos métodos, la clase puede fácilmente exceder 10k LOC.

Las clases parciales me lo explicarán y me ayudarán a encontrar métodos rápidamente.

Las clases parciales se introducen principalmente para ayudar a los generadores de código, por lo que (los usuarios) no terminamos perdiendo todo nuestro trabajo / cambios en las clases generadas, como la clase .designer.cs de ASP.NET cada vez que regeneramos, casi todas las herramientas nuevas que generan código LINQ, EntityFrameworks, ASP.NET usan clases parciales para el código generado, por lo que podemos agregar o alterar lógicamente estos códigos generados aprovechando las clases parciales y los métodos, pero tenga mucho cuidado antes de agregar cosas al código generado usando clases parciales es más fácil si rompemos la comstackción pero peor si introducimos errores de tiempo de ejecución. Para obtener más detalles, consulte este http://www.4guysfromrolla.com/articles/071509-1.aspx

Intereting Posts