Tutorial: Crear un componente con Visual C#
Actualización: noviembre 2007
Los componentes proporcionan código reutilizable en forma de objetos. Una aplicación que utiliza el código de un componente para crear objetos y llamar a sus métodos y propiedades se conoce como cliente. Un cliente puede estar o no en el mismo ensamblado que el componente que utiliza.
Los procedimientos siguientes se basan los unos en los otros, así que el orden en que se ejecutan es importante.
Nota: |
---|
Los cuadros de diálogo y comandos de menú que se ven pueden diferir de los descritos en la Ayuda, en función de la configuración activa o la edición. Para cambiar la configuración, elija la opción Importar y exportar configuraciones en el menú Herramientas. Para obtener más información, vea Valores de configuración de Visual Studio. |
Crear el proyecto
Para crear la biblioteca de clases CDemoLib y el componente CDemo
En el menú Archivo, seleccione Nuevo y, a continuación, Proyecto para abrir el cuadro de diálogo Nuevo proyecto. Seleccione la plantilla de proyecto Biblioteca de clases en la lista de tipos de proyectos de Visual C# y escriba CDemoLib en el cuadro Nombre.
Nota: Especifique siempre el nombre de un nuevo proyecto cuando lo cree. Al hacerlo se establece el espacio de nombres de la raíz, el nombre de ensamblado y el de proyecto, y también se garantiza que el componente predeterminado esté en el espacio de nombres correcto.
En el Explorador de soluciones, haga clic con el botón secundario del mouse en CDemoLib y elija Propiedades en el menú de acceso directo. Observe que el cuadro Espacio de nombres predeterminado contiene CDemoLib.
El espacio de nombres de la raíz se utiliza para calificar los nombres de los componentes del ensamblado. Por ejemplo, si dos ensamblados proporcionan componentes denominados CDemo, puede especificar el componente CDemo utilizando CDemoLib.CDemo.
Cierre el cuadro de diálogo.
En el menú Proyecto, elija Agregar componente.
En el cuadro de diálogo Agregar nuevo elemento, seleccione Clase de componentes y escriba CDemo.cs en el cuadro Nombre. Haga clic en Agregar para crear el componente.
Se agregará un componente denominado CDemo a la biblioteca de clases.
En el Explorador de soluciones, haga clic en CDemo.cs con el botón secundario del mouse y elija Ver código en el menú de acceso directo. Se abrirá el Editor de código.
Observe : Component inmediatamente después de public partial class CDemo. Esta sección designa la clase desde la que se hereda nuestra clase. De forma predeterminada, un componente hereda de la clase Component proporcionada por el sistema. La clase Component proporciona muchas características al componente, entre ellas la capacidad de utilizar diseñadores.
En el Explorador de soluciones, haga clic con el botón secundario del mouse en Class1.cs y elija Eliminar. Así eliminará la clase predeterminada que se proporciona con la biblioteca de clases, ya que no se utilizará en este tutorial.
En el menú Archivo, elija Guardar todo para guardar el proyecto.
Agregar constructores y destructores
Los constructores controlan el modo en que se inicializa el componente; el método Finalize controla la forma en que se destruye. El código del constructor y del método Finalize de la clase CDemo mantiene un recuento actualizado del número de objetos CDemo existentes.
Para agregar código para el constructor y el destructor de la clase CDemo
En el Editor de código, agregue variables miembro para mantener un total actualizado de las instancias de la clase CDemo y un número de identificador para cada instancia.
public readonly int InstanceID; private static int NextInstanceID = 0; private static long ClassInstanceCount = 0;
Dado que las variables miembro InstanceCount y NextInstanceID se declaran static, sólo existen en el nivel de clase. Todas las instancias de CDemo que tengan acceso a estos miembros utilizarán las mismas ubicaciones de memoria. Los miembros estáticos se inicializarán la primera vez que se hace referencia en el código a la clase CDemo. Podría ser la primera vez que se crea un objeto CDemo o la primera vez a la que se tiene acceso a uno de los miembros estáticos.
Busque public CDemo() y public CDemo(IContainer container), los constructores predeterminados de la clase CDemo. En Visual C#, todos los constructores tienen el mismo nombre que la clase. El componente puede tener varios constructores, con diferentes parámetros, pero todos deben tener el mismo nombre que el propio componente.
Nota: El nivel de acceso de los constructores determina qué clientes podrán crear instancias de la clase.
Agregue el código siguiente a public CDemo() para incrementar el recuento de instancias cuando se cree un nueva instancia de CDemo, así como para establecer el número de identificador de instancia.
Nota: Agregue siempre el código después de la llamada a InitializeComponent. En este momento, todos los componentes constituyentes se habrán inicializado.
InstanceID = NextInstanceID ++; ClassInstanceCount ++;
Como miembro readonly , InstanceID sólo se puede establecer en el constructor.
Nota: Los usuarios que conozcan la programación multiproceso observarán que la asignación InstanceID y el incremento de NextInstanceID debe ser una operación atómica. Éste y otros problemas relacionados con los subprocesos se muestran en Tutorial: Crear un componente sencillo con múltiples procesos en Visual C#.
Agregue el método siguiente después del final del constructor:
~CDemo() { ClassInstanceCount --; }
Este método se denomina destructor y se señala por medio del carácter de tilde (~) que precede al nombre de la clase. El administrador de memoria llama al destructor inmediatamente antes de reclamar definitivamente la memoria ocupada por el objeto CDemo. Al implementar un destructor, podrá ejecutar la limpieza inmediatamente antes de quitar el componente de la memoria. No obstante, como verá más adelante en este tutorial, existen buenas razones para liberar antes los recursos.
Agregar una propiedad a la clase
La clase CDemo sólo tiene una propiedad; se trata de una propiedad estática que permite que el cliente averigüe cuántos objetos CDemo hay en la memoria en un objeto dado. Los métodos pueden crearse de forma parecida.
Para crear una propiedad para la clase CDemo
Agregue la siguiente declaración de método a la clase CDemo con el fin de permitir que los clientes recuperen el número de instancias de CDemo.
public static long InstanceCount { get { return ClassInstanceCount; } }
Probar el componente
Para probar el componente, necesitará un proyecto que lo utilice. Este proyecto debe ser el primero que se inicie al presionar el botón Ejecutar.
Para agregar el proyecto de cliente CDemoTest como proyecto inicial para la solución
En el menú Archivo, seleccione Agregar y elija Nuevo proyecto para abrir el cuadro de diálogo Agregar nuevo proyecto.
Seleccione la plantilla de proyecto Aplicación para Windows, y escriba CDemoTest en el cuadro Nombre; a continuación, haga clic en Aceptar.
En el Explorador de soluciones, haga clic con el botón secundario del mouse en CDemoTest y haga clic en Establecer como proyecto de inicio en el menú de acceso directo.
Para utilizar el componente CDemo, el proyecto cliente de prueba debe incluir una referencia al proyecto de la biblioteca de clases. Después de agregar la referencia, es una buena idea agregar una instrucción using a la aplicación de prueba, para simplificar el uso del componente.
Para agregar una referencia al proyecto de biblioteca de clases
En el Explorador de soluciones, haga clic con el botón secundario del mouse en el nodo Referencias, justo debajo de CDemoTest, y elija Agregar referencia en el menú de acceso directo.
En el cuadro de diálogo Agregar referencia, seleccione la ficha Proyectos.
Haga doble clic en el proyecto de la biblioteca de clases CDemoLib. CDemoLib aparecerá bajo el nodo Referencias del proyecto CDemoTest.
En el Explorador de soluciones, haga clic con el botón secundario del mouse en Form1.cs y seleccione Ver código en el menú de acceso directo.
Si agrega la referencia a CDemoLib, podrá utilizar el nombre completo del componente CDemo, es decir, CDemoLib.CDemo.
Para agregar una instrucción using
Agregue la instrucción using siguiente a la lista de instrucciones using situadas al principio del Editor de código para Form1.
using CDemoLib;
Si agrega la instrucción using, podrá omitir el nombre de biblioteca y hacer referencia al tipo de componente como CDemo.
Ahora creará y utilizará un programa de prueba para probar el componente.
Vida del objeto
El programa CDemoTest ilustrará la vida del objeto en .NET Framework mediante la creación y liberación de grandes cantidades de objetos CDemo.
Para agregar código de creación y liberación de objetos CDemo
Haga clic en Form1.cs[Diseño] para volver al diseñador.
Arrastre un control Button y un control Timer desde la ficha Todos los formularios Windows Forms del Cuadro de herramientas a la superficie de diseño Form1.
El componente Timer, no visual, aparece en una superficie de diseño separada, debajo del formulario.
Haga doble clic en el icono de timer1 para crear un método de control de evento para el evento Tick del componente timer1. Inserte el código siguiente en el método de control de eventos.
this.Text = "CDemo instances: " + CDemo.InstanceCount;
A cada paso del temporizador, el título del formulario mostrará el recuento actual de instancias de la clase CDemo. El nombre de clase se utiliza como calificador de la propiedad InstanceCount; no es necesario crear una instancia de CDemo para tener acceso a un miembro estático.
Busque el constructor de Form1 (public Form1()) y agregue el código siguiente después de la llamada a InitializeComponent().
timer1.Enabled = true;
Esto iniciará el temporizador tan pronto como se cree el formulario.
Haga clic en la ficha Form1.cs [Diseño] para volver al diseñador.
Haga doble clic en Button de Form1, para crear un método de control de eventos para el evento Click. Inserte el código siguiente en el método de control de eventos.
CDemo cd; int ct; for (ct = 0; ct < 1000; ct++) cd = new CDemo();
Es posible que este código le parezca extraño. Al crearse cada instancia de CDemo se libera la instancia anterior. Cuando se termine el bucle for, sólo quedará una instancia de CDemo. Al salir del método de control de eventos, incluso esta instancia será liberada, puesto que la variable cd quedará fuera de su ámbito.
Como ya habrá supuesto, las cosas no suceden de este modo.
Para ejecutar y depurar los proyectos CDemoTest y CDemo
Presione F5 para iniciar la solución.
Se iniciará el proyecto de cliente y se mostrará el formulario Form1. Observe que el título del formulario muestra "CDemo instances: 0".
Haga clic en el botón. El título del formulario debe mostrar "CDemo instances: 1000".
Todas las instancias de CDemo se liberaron en el momento en que terminó el procedimiento de control del evento Click del botón. ¿Porqué no finalizaron? En pocas palabras, el administrador de memoria finaliza los objetos en segundo plano, con baja prioridad. La prioridad sólo aumenta si empieza a escasear la memoria del sistema. Este esquema lento de recolección de elementos no utilizados permite asignar objetos con mucha rapidez.
Haga clic en el botón varias veces más y observe el título. En algún momento, el número de instancias se reducirá repentinamente. Esto significa que el administrador de memoria reclamó la memoria de parte de los objetos.
Nota: Si hace clic más de 10 veces y el número de instancias de CDemo no se reduce, es posible que necesite ajustar el código para que utilice más memoria. Cierre el formulario para volver al entorno de desarrollo y aumente el número de iteraciones del bucle for a 10000. A continuación, ejecute de nuevo el proyecto.
Repita el paso 3. Esta vez deberá esperar más antes de que el administrador de memoria finalice más objetos.
De hecho, cada vez que repita el paso 3, podrá asignar, probablemente, más objetos CDemo antes de que intervenga el administrador de memoria. Esto se debe a que se intercambia cada vez más memoria de Visual Studio, dejando más espacio para instancias de CDemo.
Cierre el formulario para volver al entorno de programación.