CSharp
Tutorial CSharp: Delegados
Aprende los fundamentos de delegados en C#, incluyendo sintaxis, Action, Func, Predicate y delegados multicast para programación avanzada.
Aprende CSharp y certifícateDefinición y sintaxis
Los delegados en C# son tipos de referencia que representan métodos con una firma específica. Funcionan como punteros a métodos, permitiendo pasar métodos como parámetros, almacenarlos como variables o devolverlos como valores de retorno. Esta característica es fundamental para implementar callbacks, eventos y programación asíncrona.
Un delegado define un tipo que especifica una firma de método particular, incluyendo el tipo de retorno y los parámetros. Cualquier método que coincida con esa firma puede ser asignado a una variable de ese tipo delegado.
Declaración de un delegado
La sintaxis para declarar un delegado es la siguiente:
[modificadores] delegate TipoRetorno NombreDelegado([parámetros]);
Donde:
- modificadores: pueden ser
public
,internal
,private
, etc. - TipoRetorno: es el tipo de dato que devolverá el método referenciado
- NombreDelegado: es el nombre del tipo delegado (por convención suelen terminar en "Delegate" o "Handler")
- parámetros: lista opcional de parámetros que debe tener el método referenciado
Veamos un ejemplo sencillo:
// Declaración de un delegado que acepta un string y devuelve un int
public delegate int ProcesadorTextoDelegate(string texto);
Este delegado puede referenciar cualquier método que acepte un string como parámetro y devuelva un int.
Uso básico de delegados
Para utilizar un delegado, primero debemos crear una instancia y asignarle un método compatible:
using System;
class Program
{
// Declaración del delegado
public delegate void MensajeDelegate(string mensaje);
static void Main()
{
// Creación de una instancia del delegado que apunta al método MostrarMensaje
MensajeDelegate delegado = MostrarMensaje;
// Invocación del delegado
delegado("Hola desde un delegado");
// Asignación de otro método al mismo delegado
delegado = MostrarMensajeEnMayusculas;
// Invocación del delegado con el nuevo método
delegado("Hola desde un delegado");
}
static void MostrarMensaje(string mensaje)
{
Console.WriteLine($"Mensaje: {mensaje}");
}
static void MostrarMensajeEnMayusculas(string mensaje)
{
Console.WriteLine($"Mensaje: {mensaje.ToUpper()}");
}
}
En este ejemplo, creamos un delegado llamado MensajeDelegate
que puede referenciar cualquier método que acepte un string y no devuelva nada (void). Luego, creamos una instancia del delegado y le asignamos el método MostrarMensaje
. Cuando invocamos el delegado, se ejecuta el método referenciado.
Métodos anónimos con delegados
También podemos asignar métodos anónimos a los delegados, sin necesidad de definir un método con nombre:
using System;
class Program
{
public delegate int CalculadoraDelegate(int a, int b);
static void Main()
{
// Usando un método anónimo
CalculadoraDelegate suma = delegate(int x, int y) {
return x + y;
};
int resultado = suma(5, 3);
Console.WriteLine($"Resultado: {resultado}"); // Muestra: Resultado: 8
}
}
Delegados como parámetros
Una de las aplicaciones más útiles de los delegados es pasarlos como parámetros a otros métodos:
using System;
class Program
{
public delegate bool FiltradorDelegate(int numero);
static void Main()
{
int[] numeros = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Filtrar números pares
MostrarNumerosFiltrados(numeros, EsPar);
// Filtrar números mayores que 5
MostrarNumerosFiltrados(numeros, n => n > 5);
}
static void MostrarNumerosFiltrados(int[] numeros, FiltradorDelegate filtro)
{
Console.WriteLine("Números filtrados:");
foreach (int n in numeros)
{
if (filtro(n))
{
Console.Write($"{n} ");
}
}
Console.WriteLine();
}
static bool EsPar(int numero)
{
return numero % 2 == 0;
}
}
En este ejemplo, el método MostrarNumerosFiltrados
acepta un delegado como parámetro, lo que permite cambiar el comportamiento del filtrado sin modificar el método.
Expresiones lambda con delegados
Las expresiones lambda proporcionan una sintaxis más concisa para crear delegados:
using System;
class Program
{
public delegate int OperacionDelegate(int x, int y);
static void Main()
{
// Usando expresión lambda
OperacionDelegate multiplicar = (x, y) => x * y;
int resultado = multiplicar(4, 5);
Console.WriteLine($"4 x 5 = {resultado}"); // Muestra: 4 x 5 = 20
}
}
La expresión lambda (x, y) => x * y
es equivalente a definir un método que multiplica dos números, pero con una sintaxis más compacta.
Compatibilidad de covarianza y contravarianza
Los delegados en C# soportan covarianza para tipos de retorno y contravarianza para parámetros:
using System;
class Animal { }
class Perro : Animal { }
class Program
{
delegate Animal CreadorAnimalDelegate();
delegate void ManejadorAnimalDelegate(Animal animal);
static void Main()
{
// Covarianza: un método que devuelve Perro puede asignarse a un delegado que devuelve Animal
CreadorAnimalDelegate creador = CrearPerro;
// Contravarianza: un método que acepta Animal puede asignarse a un delegado que acepta Perro
ManejadorAnimalDelegate manejador = ManejarAnimal;
}
static Perro CrearPerro()
{
return new Perro();
}
static void ManejarAnimal(Animal animal)
{
Console.WriteLine("Manejando un animal");
}
}
Los delegados son un concepto fundamental en C# que permite implementar patrones de diseño avanzados y facilita la programación orientada a eventos. En las siguientes secciones, exploraremos los delegados predefinidos (Action, Func, Predicate) y los delegados multicast.
Action, Func, Predicate
C# proporciona varios delegados genéricos predefinidos que simplifican el trabajo con métodos como parámetros. Estos delegados integrados en el framework eliminan la necesidad de definir delegados personalizados para casos de uso comunes, haciendo el código más limpio y estandarizado.
Delegado Action
El delegado Action representa un método que no devuelve un valor (void) y puede aceptar de 0 a 16 parámetros. Es ideal para operaciones que realizan una acción sin necesidad de retornar información.
La familia de delegados Action incluye:
// Sin parámetros
Action miAccion = () => Console.WriteLine("Acción ejecutada");
// Con un parámetro
Action<string> mostrarMensaje = mensaje => Console.WriteLine(mensaje);
// Con múltiples parámetros
Action<string, int> repetirMensaje = (mensaje, veces) => {
for (int i = 0; i < veces; i++)
Console.WriteLine(mensaje);
};
Veamos un ejemplo práctico:
using System;
class Program
{
static void Main()
{
// Crear instancias de Action
Action saludar = () => Console.WriteLine("¡Hola mundo!");
Action<string> saludarPersona = nombre => Console.WriteLine($"¡Hola {nombre}!");
Action<string, string> saludarCompleto = (nombre, apellido) =>
Console.WriteLine($"¡Hola {nombre} {apellido}!");
// Invocar los delegados
saludar(); // Muestra: ¡Hola mundo!
saludarPersona("Ana"); // Muestra: ¡Hola Ana!
saludarCompleto("Juan", "Pérez"); // Muestra: ¡Hola Juan Pérez!
// Usar Action como parámetro
ProcesarDatos("Datos importantes", MostrarInformacion);
ProcesarDatos("Datos críticos", datos => Console.WriteLine($"URGENTE: {datos}"));
}
static void MostrarInformacion(string info)
{
Console.WriteLine($"INFO: {info}");
}
static void ProcesarDatos(string datos, Action<string> procesador)
{
// Realizar algún procesamiento...
Console.WriteLine("Procesando datos...");
// Llamar al delegado
procesador(datos);
}
}
Delegado Func
El delegado Func representa un método que devuelve un valor y puede aceptar de 0 a 16 parámetros. El último parámetro de tipo en la definición genérica siempre representa el tipo de retorno.
// Sin parámetros, devuelve string
Func<string> obtenerSaludo = () => "¡Hola mundo!";
// Un parámetro int, devuelve bool
Func<int, bool> esPar = numero => numero % 2 == 0;
// Dos parámetros int, devuelve int
Func<int, int, int> sumar = (a, b) => a + b;
Ejemplo de uso de Func en un contexto más elaborado:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
// Crear instancias de Func
Func<DateTime> obtenerFechaActual = () => DateTime.Now;
Func<int, int, int> calcularPotencia = (baseNum, exponente) => {
return (int)Math.Pow(baseNum, exponente);
};
// Invocar los delegados
Console.WriteLine($"Fecha actual: {obtenerFechaActual()}");
Console.WriteLine($"2^3 = {calcularPotencia(2, 3)}"); // Muestra: 2^3 = 8
// Usar Func para transformar datos
List<int> numeros = new List<int> { 1, 2, 3, 4, 5 };
List<int> cuadrados = TransformarLista(numeros, n => n * n);
Console.WriteLine("Cuadrados:");
foreach (int num in cuadrados)
{
Console.Write($"{num} "); // Muestra: 1 4 9 16 25
}
}
static List<T2> TransformarLista<T1, T2>(List<T1> lista, Func<T1, T2> transformador)
{
List<T2> resultado = new List<T2>();
foreach (T1 item in lista)
{
resultado.Add(transformador(item));
}
return resultado;
}
}
Delegado Predicate
El delegado Predicate es un caso especial que representa un método que recibe un parámetro y devuelve un valor booleano. Es equivalente a Func<T, bool>
y se utiliza principalmente para operaciones de filtrado.
// Predicate<T> siempre devuelve bool
Predicate<int> esMayorDeEdad = edad => edad >= 18;
Predicate<string> esCorreoValido = correo => correo.Contains("@") && correo.Contains(".");
Ejemplo práctico con Predicate:
using System;
using System.Collections.Generic;
class Producto
{
public string Nombre { get; set; }
public decimal Precio { get; set; }
public string Categoria { get; set; }
}
class Program
{
static void Main()
{
List<Producto> productos = new List<Producto>
{
new Producto { Nombre = "Laptop", Precio = 1200, Categoria = "Electrónica" },
new Producto { Nombre = "Teléfono", Precio = 800, Categoria = "Electrónica" },
new Producto { Nombre = "Mesa", Precio = 300, Categoria = "Muebles" },
new Producto { Nombre = "Silla", Precio = 150, Categoria = "Muebles" }
};
// Filtrar productos caros (más de 500)
Predicate<Producto> esProductoCaro = p => p.Precio > 500;
List<Producto> productosCostosos = productos.FindAll(esProductoCaro);
Console.WriteLine("Productos costosos:");
foreach (var producto in productosCostosos)
{
Console.WriteLine($"- {producto.Nombre}: {producto.Precio:C}");
}
// Filtrar por categoría usando método separado
List<Producto> electronicos = FiltrarPorCategoria(productos, "Electrónica");
Console.WriteLine("\nProductos electrónicos:");
foreach (var producto in electronicos)
{
Console.WriteLine($"- {producto.Nombre}");
}
}
static List<T> FiltrarPorCategoria<T>(List<T> items, string categoria) where T : Producto
{
// Usando Predicate como parámetro implícito
return items.FindAll(item => item.Categoria == categoria);
}
}
Comparación y elección entre Action, Func y Predicate
La elección entre estos delegados predefinidos depende del propósito específico:
- Action: Cuando necesites ejecutar un método que no devuelve valor (void).
- Func: Cuando necesites un método que devuelva un valor de cualquier tipo.
- Predicate: Cuando necesites un método que evalúe una condición y devuelva true/false.
Ejemplo comparativo:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<int> numeros = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Action - Realizar una operación sin devolver valor
Action<int> mostrar = n => Console.Write($"{n} ");
Console.Write("Todos los números: ");
numeros.ForEach(mostrar);
Console.WriteLine();
// Func - Transformar valores
Func<int, string> formatear = n => $"Número: {n}";
List<string> textos = numeros.ConvertAll(n => formatear(n));
Console.WriteLine($"Primer texto formateado: {textos[0]}");
// Predicate - Filtrar valores
Predicate<int> esDivisiblePorTres = n => n % 3 == 0;
List<int> divisiblesPorTres = numeros.FindAll(esDivisiblePorTres);
Console.Write("Divisibles por tres: ");
divisiblesPorTres.ForEach(mostrar);
}
}
Estos delegados predefinidos son ampliamente utilizados en la programación moderna con C#, especialmente en:
- LINQ: Las consultas LINQ utilizan Func y Predicate internamente.
- Programación asíncrona: Los métodos Task utilizan Action y Func.
- Eventos y callbacks: Action se usa frecuentemente para manejar eventos.
- Algoritmos de colecciones: Los métodos de List como ForEach, Find, etc.
La comprensión y uso adecuado de estos delegados predefinidos es fundamental para escribir código C# moderno, conciso y mantenible.
Delegados multicast
Los delegados multicast son una característica poderosa de C# que permite que un solo delegado apunte a múltiples métodos. Cuando se invoca un delegado multicast, todos los métodos referenciados se ejecutan secuencialmente en el orden en que fueron agregados. Esta funcionalidad es especialmente útil para implementar sistemas de notificación, donde múltiples componentes necesitan responder a un mismo evento.
En C#, todos los delegados son inherentemente multicast gracias a que derivan de la clase base MulticastDelegate
, que a su vez hereda de Delegate
. Esto significa que cualquier delegado que definamos puede comportarse como un delegado multicast.
Operaciones con delegados multicast
Para crear un delegado multicast, utilizamos los operadores +=
y -=
para agregar o quitar métodos:
using System;
class Program
{
// Definición del delegado
public delegate void Notificador(string mensaje);
static void Main()
{
// Creamos un delegado vacío
Notificador notificacion = null;
// Agregamos métodos al delegado
notificacion += EnviarEmail;
notificacion += EnviarSMS;
notificacion += MostrarEnConsola;
// Invocamos el delegado multicast
Console.WriteLine("Enviando notificación a todos los canales:");
notificacion?.Invoke("Sistema iniciado correctamente");
Console.WriteLine("\nQuitando notificación por SMS:");
// Quitamos un método del delegado
notificacion -= EnviarSMS;
// Invocamos nuevamente
notificacion?.Invoke("Actualización completada");
}
static void EnviarEmail(string mensaje)
{
Console.WriteLine($"EMAIL: {mensaje}");
}
static void EnviarSMS(string mensaje)
{
Console.WriteLine($"SMS: {mensaje}");
}
static void MostrarEnConsola(string mensaje)
{
Console.WriteLine($"CONSOLA: {mensaje}");
}
}
En este ejemplo, creamos un delegado multicast notificacion
que apunta a tres métodos diferentes. Al invocar el delegado, los tres métodos se ejecutan en secuencia. Luego, quitamos uno de los métodos y al invocar nuevamente, solo se ejecutan los dos restantes.
Consideraciones sobre el valor de retorno
Un aspecto importante a tener en cuenta es que los delegados multicast solo pueden devolver valores de manera efectiva cuando el tipo de retorno es void
. Si el delegado tiene un tipo de retorno no void, solo se devolverá el valor del último método ejecutado:
using System;
class Program
{
public delegate int Calculador(int x, int y);
static void Main()
{
// Creamos un delegado multicast con tipo de retorno no void
Calculador operaciones = Sumar;
operaciones += Restar;
operaciones += Multiplicar;
// Al invocar, solo obtenemos el resultado del último método (Multiplicar)
int resultado = operaciones(10, 5);
Console.WriteLine($"Resultado: {resultado}"); // Muestra: Resultado: 50
}
static int Sumar(int a, int b)
{
int resultado = a + b;
Console.WriteLine($"Suma: {resultado}");
return resultado;
}
static int Restar(int a, int b)
{
int resultado = a - b;
Console.WriteLine($"Resta: {resultado}");
return resultado;
}
static int Multiplicar(int a, int b)
{
int resultado = a * b;
Console.WriteLine($"Multiplicación: {resultado}");
return resultado;
}
}
En este ejemplo, aunque los tres métodos se ejecutan y muestran sus resultados por consola, la variable resultado
solo contiene el valor devuelto por el último método ejecutado (Multiplicar).
Obtención de todos los resultados
Si necesitamos obtener los resultados de todos los métodos en un delegado multicast, podemos usar la reflexión para obtener la lista de delegados y ejecutarlos individualmente:
using System;
using System.Collections.Generic;
class Program
{
public delegate int Transformador(int valor);
static void Main()
{
// Creamos un delegado multicast
Transformador transformaciones = Duplicar;
transformaciones += Cuadrado;
transformaciones += Incrementar;
int numero = 5;
Console.WriteLine($"Número original: {numero}");
// Obtenemos todos los resultados
List<int> resultados = ObtenerTodosLosResultados(transformaciones, numero);
Console.WriteLine("Resultados de todas las transformaciones:");
foreach (int resultado in resultados)
{
Console.WriteLine($"- {resultado}");
}
}
static List<T> ObtenerTodosLosResultados<T>(Delegate delegadoMulticast, params object[] args)
{
List<T> resultados = new List<T>();
// Si el delegado no es nulo
if (delegadoMulticast != null)
{
// Obtenemos la lista de delegados individuales
foreach (Delegate delegado in delegadoMulticast.GetInvocationList())
{
// Invocamos cada delegado y guardamos su resultado
T resultado = (T)delegado.DynamicInvoke(args);
resultados.Add(resultado);
}
}
return resultados;
}
static int Duplicar(int n)
{
return n * 2;
}
static int Cuadrado(int n)
{
return n * n;
}
static int Incrementar(int n)
{
return n + 1;
}
}
Este código muestra cómo podemos obtener los resultados de todos los métodos en un delegado multicast utilizando el método GetInvocationList()
, que devuelve un array con todos los delegados individuales.
Manejo de excepciones en delegados multicast
Cuando trabajamos con delegados multicast, es importante considerar cómo manejar las excepciones. Si uno de los métodos en la cadena lanza una excepción, los métodos subsiguientes no se ejecutarán:
using System;
class Program
{
public delegate void Procesador();
static void Main()
{
Procesador proceso = PrimerPaso;
proceso += SegundoPaso;
proceso += TercerPaso;
try
{
proceso();
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
Console.WriteLine("El proceso se interrumpió.");
}
}
static void PrimerPaso()
{
Console.WriteLine("Primer paso completado");
}
static void SegundoPaso()
{
Console.WriteLine("Iniciando segundo paso...");
throw new InvalidOperationException("Error en el segundo paso");
}
static void TercerPaso()
{
Console.WriteLine("Tercer paso completado");
}
}
En este ejemplo, cuando SegundoPaso
lanza una excepción, TercerPaso
nunca se ejecuta. Si necesitamos que todos los métodos se ejecuten independientemente de las excepciones, debemos implementar un manejo de excepciones más robusto:
using System;
class Program
{
public delegate void Procesador();
static void Main()
{
Procesador proceso = PrimerPaso;
proceso += SegundoPaso;
proceso += TercerPaso;
// Ejecutamos cada delegado individualmente con manejo de excepciones
foreach (Procesador paso in proceso.GetInvocationList())
{
try
{
paso();
}
catch (Exception ex)
{
Console.WriteLine($"Error en un paso: {ex.Message}");
Console.WriteLine("Continuando con el siguiente paso...");
}
}
Console.WriteLine("Proceso completo");
}
static void PrimerPaso()
{
Console.WriteLine("Primer paso completado");
}
static void SegundoPaso()
{
Console.WriteLine("Iniciando segundo paso...");
throw new InvalidOperationException("Error en el segundo paso");
}
static void TercerPaso()
{
Console.WriteLine("Tercer paso completado");
}
}
Aplicaciones prácticas de delegados multicast
Los delegados multicast son especialmente útiles en escenarios como:
- Sistemas de notificación: Cuando múltiples componentes necesitan ser notificados de un cambio.
- Validación de datos: Ejecutar múltiples validaciones sobre un conjunto de datos.
- Procesamiento en cadena: Aplicar una serie de transformaciones a un dato.
Veamos un ejemplo de un sistema de validación simple:
using System;
using System.Collections.Generic;
class Producto
{
public string Nombre { get; set; }
public decimal Precio { get; set; }
public int Stock { get; set; }
}
class Program
{
// Delegado para validación que devuelve un mensaje de error o null si es válido
public delegate string Validador(Producto producto);
static void Main()
{
// Creamos un producto para validar
Producto producto = new Producto
{
Nombre = "",
Precio = -50,
Stock = 10
};
// Configuramos las validaciones
Validador validaciones = ValidarNombre;
validaciones += ValidarPrecio;
validaciones += ValidarStock;
// Validamos el producto
bool esValido = true;
List<string> errores = new List<string>();
foreach (Validador validador in validaciones.GetInvocationList())
{
string error = validador(producto);
if (error != null)
{
esValido = false;
errores.Add(error);
}
}
// Mostramos el resultado
if (esValido)
{
Console.WriteLine("El producto es válido");
}
else
{
Console.WriteLine("El producto tiene los siguientes errores:");
foreach (string error in errores)
{
Console.WriteLine($"- {error}");
}
}
}
static string ValidarNombre(Producto p)
{
if (string.IsNullOrWhiteSpace(p.Nombre))
return "El nombre no puede estar vacío";
return null;
}
static string ValidarPrecio(Producto p)
{
if (p.Precio <= 0)
return "El precio debe ser mayor que cero";
return null;
}
static string ValidarStock(Producto p)
{
if (p.Stock < 0)
return "El stock no puede ser negativo";
return null;
}
}
Este ejemplo muestra cómo podemos usar delegados multicast para implementar un sistema de validación flexible, donde cada validación es independiente y podemos agregar o quitar validaciones según sea necesario.
Los delegados multicast son una herramienta fundamental en C# que permite implementar patrones de diseño como Observer, Chain of Responsibility y Command de manera elegante y flexible. Su capacidad para manejar múltiples suscriptores los hace ideales para sistemas basados en eventos, donde la comunicación desacoplada entre componentes es esencial.
Ejercicios de esta lección Delegados
Evalúa tus conocimientos de esta lección Delegados con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
CRUD en C# de modelo Customer sobre una lista
Arrays y listas
Objetos
Excepciones
Eventos
Lambdas
Diccionarios en C#
Variables y constantes
Tipos de datos
Herencia
Operadores
Uso de consultas LINQ
Clases y encapsulación
Uso de consultas LINQ
Excepciones
Control de flujo
Eventos
Diccionarios
Tipos de datos
Conjuntos, colas y pilas
Lambdas
Conjuntos, colas y pilas
Uso de async y await
Tareas
Constructores y destructores
Operadores
Arrays y listas
Polimorfismo
Polimorfismo
Variables y constantes
Proyecto colecciones y LINQ en C#
Clases y encapsulación
Creación de proyecto C#
Uso de async y await
Funciones
Delegados
Delegados
Constructores y destructores
Objetos
Control de flujo
Funciones
Tareas
Proyecto sintaxis en C#
Herencia C Sharp
OOP en C Sharp
Diccionarios
Introducción a C#
Todas las lecciones de CSharp
Accede a todas las lecciones de CSharp y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A C#
Introducción Y Entorno
Creación De Proyecto C#
Introducción Y Entorno
Variables Y Constantes
Sintaxis
Tipos De Datos
Sintaxis
Operadores
Sintaxis
Control De Flujo
Sintaxis
Funciones
Sintaxis
Estructuras De Control Iterativo
Sintaxis
Interpolación De Strings
Sintaxis
Estructuras De Control Condicional
Sintaxis
Manejo De Valores Nulos
Sintaxis
Clases Y Encapsulación
Programación Orientada A Objetos
Objetos
Programación Orientada A Objetos
Constructores Y Destructores
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Genéricos
Programación Orientada A Objetos
Métodos Virtuales Y Sobrecarga
Programación Orientada A Objetos
Clases Abstractas
Programación Orientada A Objetos
Interfaces
Programación Orientada A Objetos
Propiedades Y Encapsulación
Programación Orientada A Objetos
Métodos De Extensión
Programación Orientada A Objetos
Clases Y Objetos
Programación Orientada A Objetos
Clases Parciales
Programación Orientada A Objetos
Miembros Estáticos
Programación Orientada A Objetos
Tuplas Y Tipos Anónimos
Programación Orientada A Objetos
Arrays Y Listas
Colecciones Y Linq
Diccionarios
Colecciones Y Linq
Conjuntos, Colas Y Pilas
Colecciones Y Linq
Uso De Consultas Linq
Colecciones Y Linq
Linq Avanzado
Colecciones Y Linq
Colas Y Pilas
Colecciones Y Linq
Conjuntos
Colecciones Y Linq
Linq Básico
Colecciones Y Linq
Delegados Funcionales
Programación Funcional
Records
Programación Funcional
Expresiones Lambda
Programación Funcional
Linq Funcional
Programación Funcional
Fundamentos De La Programación Funcional
Programación Funcional
Pattern Matching
Programación Funcional
Testing Unitario Con Xunit
Testing
Excepciones
Excepciones
Delegados
Programación Asíncrona
Eventos
Programación Asíncrona
Lambdas
Programación Asíncrona
Uso De Async Y Await
Programación Asíncrona
Tareas
Programación Asíncrona
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender qué son los delegados y cómo declararlos en C#.
- Aprender a utilizar delegados con métodos nombrados, anónimos y expresiones lambda.
- Conocer los delegados genéricos predefinidos Action, Func y Predicate y sus aplicaciones.
- Entender el concepto y uso de delegados multicast para invocar múltiples métodos.
- Saber manejar excepciones y obtener resultados en delegados multicast para escenarios avanzados.