93 - Delegados |
Otro concepto que incorpora el lenguaje C# son los delegados que son necesarios en conceptos muy utilizados en C# moderno como son las lambdas y LINQ.
Un delegado almacena la referencia de un método con una estructura definida (en cuanto al tipo de dato que devuelve y los tipos y cantidad de parámetros)
Un ejemplo de sintaxis para declarar un delegado:
delegate void delegadoA(int x, int y);
Un delegado comienza con la palabra clave delegate. Luego se declara la firma del método (tipo de dato que retorna, los parámetros y el nombre del delegado)
Declarar un delegado que reciba dos enteros y retorne un entero.
Plantear una clase Operacion y los métodos que permitan sumar y restar dos enteros.
Llamar a los métodos mediante la definición de un delegado.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Delegados1
{
delegate int Operar(int x1, int x2);
class Program
{
public int Sumar(int x, int y)
{
return x + y;
}
public int Restar(int x, int y)
{
return x - y;
}
static void Main(string[] args)
{
Program p = new Program();
Console.WriteLine("Suma y resta de dos valores llamando directamente a los métodos.");
Console.WriteLine(p.Sumar(10, 5));
Console.WriteLine(p.Restar(10, 5));
Operar delegado = p.Sumar;
Console.WriteLine("Suma y resta de dos valores llamando a los métodos a través de delegados");
Console.WriteLine(delegado(10, 5));
delegado = p.Restar;
Console.WriteLine(delegado(10, 5));
Console.ReadKey();
}
}
}
Declaramos el delegado Operar que recibe dos parámetros de tipo int y retorna un int:
delegate int Operar(int x1, int x2);
En la clase Program definimos dos métodos Sumar y Restar que tienen una firma idéntica al delegado Operar:
class Program
{
public int Sumar(int x, int y)
{
return x + y;
}
public int Restar(int x, int y)
{
return x - y;
}
En el método Main definimos un objeto de la clase Program y llamamos directamente sus dos métodos:
static void Main(string[] args)
{
Program p = new Program();
Console.WriteLine("Suma y resta de dos valores llamando directamente a los métodos.");
Console.WriteLine(p.Sumar(10, 5));
Console.WriteLine(p.Restar(10, 5));
Lo nuevo aparece cuando definimos un objeto del tipo delegado Operar y le cargamos la referencia del método Sumar:
Operar delegado = p.Sumar;
La variable delegado tiene ahora la referencia del método Sumar y podemos llamar a dicho método a través del delegado:
Console.WriteLine(delegado(10, 5));
Luego modificamos la variable delegado y almacenamos la referencia al método Restar y llamamos a dicho método a través del delegado:
delegado = p.Restar;
Console.WriteLine(delegado(10, 5));
En este problema no tiene ninguna ventaja definir un delegado y llamar a los métodos Sumar y Restar a través de delegados. Hemos presentado este problema con el objetivo de comenzar a entender la sintaxis de como se declara un delegado y que almacena una variable de este tipo. A medida que avancemos veremos las ventajas de delegados cuando definamos lambdas y entremos al tema de LINQ.
Un método puede recibir como parámetro un delegado y a partir de esto llamar al método que almacena el delegado.
Declarar un delegado que reciba dos enteros y retorne un entero.
Plantear una clase Operacion y los métodos que permitan sumar y restar dos enteros. Un tercer método que reciba un delegado y dos enteros.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Delegados2
{
delegate int Operar(int x1, int x2);
class Program
{
public int Sumar(int x, int y)
{
return x + y;
}
public int Restar(int x, int y)
{
return x - y;
}
public void operacion(Operar d, int x, int y)
{
Console.WriteLine(d(10, 5));
}
static void Main(string[] args)
{
Program p = new Program();
Console.WriteLine("Suma y resta de 10 y 5.");
p.operacion(p.Sumar, 10, 5);
p.operacion(p.Restar, 10, 5);
Console.ReadKey();
}
}
}
Declaramos el delegado:
delegate int Operar(int x1, int x2);
Declaramos la clase Program y los dos métodos que suman y restan dos enteros:
class Program
{
public int Sumar(int x, int y)
{
return x + y;
}
public int Restar(int x, int y)
{
return x - y;
}
Lo nuevo aparece en el método operacion que recibe en el primer parámetro un delegado de tipo Operar y dos enteros. Dentro del algoritmo del método se llama al método que almacena el delegado:
public void operacion(Operar d, int x, int y)
{
Console.WriteLine(d(10, 5));
}
En la función Main luego de crear un objeto de la clase Program procedemos a llamar solo al método operacion y pasar en el primer parámetro la referencia del método Sumar o Restar según la actividad que necesitamos hacer con los dos enteros restantes:
static void Main(string[] args)
{
Program p = new Program();
Console.WriteLine("Suma y resta de 10 y 5.");
p.operacion(p.Sumar, 10, 5);
p.operacion(p.Restar, 10, 5);
Console.ReadKey();
}