Menu
Coddy logo textTech

Delegados y eventos

Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy. Lección 43 de 70.

Un delegado es un tipo que representa una referencia a un método. Piensa en él como una variable que contiene un método en lugar de datos. Esto te permite pasar métodos como argumentos, almacenarlos en colecciones y llamarlos dinámicamente.

Declaras un delegado especificando la firma del método al que puede hacer referencia:

public delegate void Notify(string message);

public class Publisher
{
    public void SendAlert(string msg) => Console.WriteLine("Alert: " + msg);
}

// Uso
Notify notifier = new Publisher().SendAlert;
notifier("System started");  // Alerta: Sistema iniciado

Los eventos se basan en delegados para implementar el patrón de publicación-suscripción. Una clase activa un evento y otras clases pueden suscribirse para recibir notificaciones. La palabra clave event restringe cómo se puede usar el delegado: los suscriptores solo pueden agregar o quitar controladores, no invocar el evento directamente.

public class Button
{
    public event Action Clicked;
    
    public void Click()
    {
        Clicked?.Invoke();  // Notificar a todos los suscriptores
    }
}

// Suscribiendo
Button btn = new Button();
btn.Clicked += () => Console.WriteLine("Button was clicked!");
btn.Click();  // ¡Se hizo clic en el botón!

El operador += suscribe un controlador, mientras que -= cancela la suscripción. El patrón ?.Invoke() llama al evento de forma segura solo si hay suscriptores. Los eventos son fundamentales para las aplicaciones con GUI, los motores de juegos y cualquier sistema en el que los objetos deban reaccionar a los cambios sin un acoplamiento estrecho.

challenge icon

Desafío

Fácil

Construyamos un sistema de monitoreo de temperatura que use delegados y eventos para notificar a los suscriptores cada vez que cambie la temperatura. Este es un ejemplo clásico del patrón de publicación-suscripción que los eventos permiten implementar con tanta elegancia.

Organizarás tu código en dos archivos:

  • TemperatureMonitor.cs: Crea una clase TemperatureMonitor en el espacio de nombres Monitoring que actúe como publicador. Tu monitor debe:
    • Tener un campo privado para almacenar la temperatura actual
    • Declarar un evento mediante Action<int> llamado TemperatureChanged que se active cada vez que se actualice la temperatura
    • Tener una propiedad Temperature (int) cuyo establecedor actualice el campo privado y active el evento con el nuevo valor de temperatura
    Recuerda usar el patrón ?.Invoke() para activar el evento de forma segura solo cuando haya suscriptores.
  • Program.cs: En tu archivo principal, crea un TemperatureMonitor y suscribe dos controladores diferentes a su evento TemperatureChanged:
    • Un controlador que imprima: Alert: Temperature is now {value} degrees
    • Otro controlador que imprima: Logged: {value}
    Después de suscribir ambos controladores, establece la temperatura dos veces usando valores de la entrada. Cada vez que establezcas la temperatura, ambos controladores deben responder.

Recibirás dos entradas:

  • Primer valor de temperatura (entero)
  • Segundo valor de temperatura (entero)

Por ejemplo, si las entradas son 25 y 30, la salida debe ser:

Alert: Temperature is now 25 degrees
Logged: 25
Alert: Temperature is now 30 degrees
Logged: 30

Observa cómo establecer la propiedad Temperature notifica automáticamente a todos los suscriptores: el monitor no necesita saber nada sobre quién está escuchando. ¡Esa es la belleza del enfoque basado en eventos!

Pruébalo tú mismo

using System;
using Monitoring;

class Program
{
    public static void Main(string[] args)
    {
        // Leer entrada
        int temp1 = Convert.ToInt32(Console.ReadLine());
        int temp2 = Convert.ToInt32(Console.ReadLine());

        // TODO: Crea una instancia de TemperatureMonitor

        // TODO: Subscribe a handler that prints: "Alert: Temperature is now {value} degrees"

        // TODO: Suscribe otro manejador que imprima: "Logged: {value}"

        // TODO: Establece la temperatura a temp1

        // TODO: Establece la temperatura a temp2
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C# online