que - ¿Cuándo es apropiado usar clases parciales de C#?
que es una clase en c# (21)
- Desarrollador múltiple usando clases parciales El desarrollador múltiple puede trabajar en la misma clase fácilmente.
- Generador de código Las clases parciales las utiliza principalmente el generador de código para mantener separadas las diferentes inquietudes
- Métodos parciales usando clases parciales, también puede definir métodos parciales y un desarrollador puede simplemente definir el método y el otro desarrollador puede implementarlo.
Solo declaración parcial del método Incluso el código se compila solo con la declaración del método y, si la implementación del método no está presente, el compilador puede eliminar esa parte del código de forma segura y no se producirá un error de tiempo de compilación.
Para verificar el punto 4. Simplemente cree un proyecto winform e incluya esta línea después del Form1 Constructor e intente compilar el código
partial void Ontest(string s);
Aquí hay algunos puntos a considerar al implementar clases parciales:
- Use palabra clave parcial en cada parte de la clase parcial.
- El nombre de cada parte de la clase parcial debe ser el mismo, pero el nombre del archivo fuente para cada parte de la clase parcial puede ser diferente.
- Todas las partes de una clase parcial deben estar en el mismo espacio de nombres.
- Cada parte de una clase parcial debe estar en el mismo conjunto o DLL, en otras palabras, no puede crear una clase parcial en los archivos de origen de un proyecto de biblioteca de clases diferente.
- Cada parte de una clase parcial debe tener la misma accesibilidad. (es decir, privado, público o protegido)
- Si hereda una clase o interfaz en una clase parcial, todas las partes de esa clase parcial lo heredan.
- Si una parte de una clase parcial está sellada, toda la clase será sellada.
- Si una parte de la clase parcial es abstracta, toda la clase se considerará una clase abstracta.
Me preguntaba si alguien podría darme una descripción de por qué los usaría y qué ventaja obtendría en el proceso.
Aparte de las otras respuestas ...
Los he encontrado útiles como un trampolín para refactorizar las clases de dioses. Si una clase tiene múltiples responsabilidades (especialmente si es un archivo de código muy grande), me parece beneficioso agregar una clase parcial de responsabilidad por primera vez como primer paso para organizar y luego refactorizar el código.
Esto es de gran ayuda porque puede ayudar a hacer que el código sea mucho más legible sin afectar realmente 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 que quede claro, esto sigue siendo un código incorrecto, al final del desarrollo aún desea una responsabilidad por clase ( NO por clase parcial). Es solo un peldaño :)
Aquí hay una lista de algunas de las ventajas de las clases parciales.
Puede separar el código de diseño de UI y el código de lógica de negocios para que sea fácil de leer y entender. Por ejemplo, si está desarrollando una aplicación web con Visual Studio y agrega un nuevo formulario web, existen dos archivos de origen, "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 una definición de control de interfaz de usuario.
Cuando se trabaja 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 interfaz de usuario, pero no desea agregar una nueva columna a la tabla de la base de datos para que pueda crear un archivo de origen independiente para esta clase que tenga una nueva propiedad para esa columna y se ser una clase parcial. Así que eso afecta la asignación entre la tabla de base de datos y la entidad DBML, pero puede obtener fácilmente un campo adicional. Esto significa que puede escribir el código por su cuenta sin alterar el código generado por el sistema.
Más de un desarrollador puede escribir simultáneamente el código para la clase.
Puede mantener mejor su aplicación al compactar grandes clases. Supongamos que tiene una clase que tiene múltiples interfaces, por lo que puede crear múltiples archivos de origen según los implementos de la interfaz. Es fácil de entender y mantener una interfaz implementada en la que el archivo de origen tiene una clase parcial.
Cada vez que tengo una clase que contiene una clase anidada que tiene un tamaño / complejidad significativa, marco la clase como partial
y coloco la clase anidada en un archivo separado. Nombro el archivo que contiene la clase anidada usando la regla: [nombre de clase]. [Nombre de clase anidada] .cs.
El siguiente blog de MSDN explica cómo usar clases parciales con clases anidadas para mantener: http://blogs.msdn.com/b/marcelolr/archive/2009/04/13/using-partial-classes-with-nested-classes-for-maintainability.aspx
Como alternativa a las directivas pre-compilador.
Si usa directivas de #IF DEBUG
(a saber, #IF DEBUG
), entonces terminará con un código de aspecto retorcido mezclado con su 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 compilador (efectivamente haciendo lo mismo).
Desde MSDN :
1. En el tiempo de compilación, los atributos de las definiciones de tipo parcial se combinan. Por ejemplo, considere las siguientes declaraciones:
[SerializableAttribute]
partial class Moon { }
[ObsoleteAttribute]
partial class Moon { }
Son equivalentes a las siguientes declaraciones:
[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }
Lo siguiente se fusiona 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 { }
}
El mayor uso de las clases parciales es hacer la vida más fácil para los generadores / diseñadores de código. Las clases parciales permiten al generador simplemente emitir el código que necesitan para emitir y no tienen que lidiar con las ediciones del usuario al archivo. Los usuarios también tienen la libertad de anotar la clase con nuevos miembros al tener 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 acerca de no modificar el código. Tuvo que insertar todo tipo de heurísticas para encontrar el código generado para su posterior procesamiento. Ahora puede simplemente abrir el archivo designer.cs y tener un alto grado de confianza de que solo contiene código relevante para el diseñador.
El uso principal para las clases parciales es con el código generado. Si observa la red WPF (Windows Presentation Foundation), define su interfaz de usuario con el marcado (XML). Ese marcado se compila en clases parciales. Usted completa el código con clases parciales propias.
Es cierto que Partial Class se usa en la generación de código automático, un uso puede ser mantener un archivo de clase grande que podría tener miles de líneas de código. Nunca se sabe que su clase podría terminar con 10 mil líneas y no desea crear una nueva clase 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 uso posible podría ser que más de un desarrollador pueda trabajar en la misma clase que están almacenados en diferentes lugares. La gente puede reírse, pero nunca se sabe que puede ser útil 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!
La mayoría de las personas comentan que partial
solo debe usarse para una clase que tiene un archivo de código generado o para interfaces. No estoy de acuerdo, y aquí es por qué.
Por ejemplo, veamos la clase C # System.Math ... esa es la clase . No intentaría meter 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 de clase parciales individuales, y todos los archivos de código en una carpeta matemática 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 de perfil privado podría beneficiarse al dividirse en un conjunto limpio de archivos de clase parciales en una sola carpeta de proyecto.
Personalmente, también divido lo que la mayoría de las personas llama clases de "ayudante" 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 cadena tiene casi 50 métodos. Ese sería un archivo de código largo y poco manejable, incluso usando regiones. Es significativamente más fácil mantener el uso de archivos de clase parciales individuales para cada método.
Debería tener cuidado al usar clases parciales y mantener todo el diseño de archivo de código consistente a lo largo del proyecto al hacer esto. Por ejemplo, colocar cualquier enumeración pública de clase y miembros de clase privada en un archivo Common.cs o de nombre similar en la carpeta, en lugar de distribuirlos a través de los archivos a menos que sean específicos solo para el archivo parcial en el que se encuentran.
Tenga en cuenta que cuando divide una clase en archivos separados, también pierde la capacidad de usar la barra divisora del editor de texto que le permite ver dos secciones diferentes de un archivo actual simultáneamente.
Las clases parciales hacen posible agregar funcionalidad a un programa diseñado adecuadamente simplemente agregando archivos de origen. Por ejemplo, un programa de importación de archivos podría diseñarse de manera que se puedan agregar diferentes tipos de archivos conocidos agregando módulos que los manejen. Por ejemplo, el convertidor de tipo de archivo principal podría incluir una clase pequeña:
Partial Public Class zzFileConverterRegistrar Event Register(ByVal mainConverter as zzFileConverter) Sub registerAll(ByVal mainConverter as zzFileConverter) RaiseEvent Register(mainConverter) End Sub End Class
Cada módulo que desee registrar uno o más tipos de convertidor de archivos podría incluir algo como:
Partial Public Class zzFileConverterRegistrar Private Sub RegisterGif(ByVal mainConverter as zzFileConverter) Handles Me.Register mainConverter.RegisterConverter("GIF", GifConverter.NewFactory)) End Sub End Class
Tenga en cuenta que la clase del convertidor de archivos principal no está "expuesta", solo expone una pequeña clase de código auxiliar a la que se pueden conectar los módulos complementarios. Existe un leve riesgo de conflictos de nombres, pero si la rutina de "registro" de cada módulo de complemento se nombra de acuerdo con el tipo de archivo con el que se trata, probablemente no deberían plantear un problema. Uno podría pegar un GUID en el nombre de la subrutina de registro si estuviera preocupado por tales cosas.
Edición / Addendum Para ser claro, el propósito de esto es proporcionar un medio por el cual una variedad de clases separadas le permita a un programa o clase principal saber sobre ellas. Lo único que hará el convertidor de archivos principal con zzFileConverterRegistrar es crear una instancia de él y llamar al método registerAll que activará el evento Register. Cualquier módulo que quiera enganchar ese evento puede ejecutar código arbitrario en respuesta a él (esa es toda la idea), pero no hay nada que pueda hacer un módulo al extender indebidamente la clase zzFileConverterRegistrar aparte de 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 esté rota simplemente la escriba correctamente.
Uno podría, sin usar clases parciales, tener un poco de código en algún lugar dentro de la clase del convertidor de archivos principal, que parecía:
RegisterConverter("GIF", GifConvertor.NewFactory) RegisterConverter("BMP", BmpConvertor.NewFactory) RegisterConverter("JPEG", JpegConvertor.NewFactory)
pero agregar otro módulo convertidor requeriría ingresar a esa parte del código del convertidor y agregar el nuevo convertidor a la lista. Usando métodos parciales, eso ya no es necesario, todos los convertidores se incluirán automáticamente.
Las clases parciales recientemente ayudaron con el control de origen donde varios desarrolladores estaban agregando a un archivo donde se agregaron nuevos métodos en la misma parte del archivo (automatizado por Resharper).
Estos empujones a git causaron 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 que los desarrolladores se adhieran a una versión de su archivo, y podemos fusionarlos de nuevo a mano a mano.
ejemplo
- MainClass.cs - contiene campos, constructor, etc.
- MainClass1.cs - un nuevo código de desarrolladores a medida que se implementan
- MainClass2.cs - es otra clase de desarrolladores para su nuevo código.
Las clases parciales se presentan 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 el código LINQ, EntityFrameworks, ASP.NET usa clases parciales para el código generado, por lo que podemos agregar o alterar de manera segura la lógica de estos códigos generados aprovechando las clases y métodos parciales, pero tenga mucho cuidado antes de agregar elementos al código generado usando clases parciales es más fácil si rompemos la compilació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
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 que se sobrescriban al actualizar la referencia del servicio.
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
}
Otro uso que vi es,
Extendiendo una gran clase abstracta con respecto a la lógica de acceso a datos,
Tengo varios archivos con 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..
}
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 programa, especialmente máquinas de estado.
Por ejemplo, OpenGL es una máquina de estado, hay montones de métodos que se pueden cambiar globalmente, sin embargo, en mi experiencia, vinculando algo similar a OpenGL donde hay tantos métodos, la clase puede superar fácilmente los 10k LOC.
Las clases parciales desglosarán esto por mí y me ayudarán a encontrar métodos rápidamente.
Si tiene una clase suficientemente grande que no se presta para una refactorización efectiva, separarla en varios 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 proxy, solo para ser claros), puede crear una sola clase parcial en diferentes archivos, como
MyProvider.cs - lógica de 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, es casi 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 plantillas (T4), ORM, etc.
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 de 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 el Diseñador va en un archivo que generalmente no se toca. Su código escrito a mano va en otro archivo. De esa manera, cuando cambias algo en Designer, tus cambios no se pierden.
mantenga todo lo más limpio posible cuando trabaje con clases grandes, o cuando trabaje en un equipo, puede editar sin anular (o siempre cometer 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 se hace a menudo por 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 es generado por una 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
Se requiere parcial aquí.
If you remove the partial modifier, you will get an error containing this text: [The namespace ''<global namespace>'' already contains a definition for ''A''].
Sugerencia: para solucionar este problema, 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 programa anterior, verá que los archivos A1.cs y A2.cs se eliminan.
Encontrarás que la clase A está presente.
Desensamblador IL: La clase A contendrá los métodos A1 y A2 en el mismo bloque de código. Las dos clases se fusionaron en una sola.
Resultado compilado 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 programación en C #.
A menudo se utilizan en Visual Studio al crear programas de Windows Forms / WPF.
El código C # generado por la máquina es separado.
O puedes encontrar la descripción completa here .