I DELEGATE

namespace Delegate
Come vedi un delegate si dichiara con la parola chiave delegate, per il resto somiglia alla definizione di un metodo, abbiamo dichiarato un tipo di ritorno int e due parametri di tipo intero a e b. È un po' come un metodo dichiarato all'interno di una interface, la particolarità è che nella dichiarazione c'è la keyword delegate. Questo particolare delegate rappresenta qualsiasi metodo che prenda in input due interi e restituisca un int.
UTILIZZO DEI DELEGATE
using System;
namespace Delegate
{
public delegate int MyDelegate(int a, int b);
class Program
{
static void Main(string[] args)
{
MyDelegate md = Somma;//PRIMA FORMA DI INIZIALIZZAZIONE DEL DELEGATE
//MyDelegate md1 = new MyDelegate(Somma);SECONDA FORMA PER INIZIALIZZARE UN DELEGATE. MENO COMUNE.
int result = md(10,5);
Console.WriteLine($"Somma: {result}");
md=Differenza;
result = md(10,5);
Console.WriteLine($"Differenza: {result}");
md=Moltiplicazione;
result = md.Invoke(10,5);//SI PUO' USARE ANCHE IL METODO Invoke PER CHIAMARE IL METODO.
Console.WriteLine($"Moltiplicazione: {result}");
static int Somma(int arg1, int arg2)
{
return arg1+arg2;
}
static int Differenza(int arg1, int arg2)
{
return arg1 - arg2;
}
static int Moltiplicazione(int arg1, int arg2)
{
return arg1 * arg2;
}
}
}
}
Come vedi dal codice sopra riportato ho dichiarato tre metodi Somma, Differenza e Moltiplicazione ognuno avente la stessa signature del delegate. Con l’istruzione
MyDelegate md = Somma;
Ho inizializzato la variabile istanza del delegate con il metodo Somma, l’invocazione di tale metodo avviene con l’istruzione:
int result = md(10,5); o con l’istruzione
int result = md.Invoke(10,5);
Una volta effettuata la somma la stessa istanza del delegate può puntare un nuovo metodo. Ho utilizzato la parola puntare perché chi ha familiarità con il linguaggio C o C++ può osservare che un delegate è simile ad un puntatore a funzione, il problema dei puntatori è che spesso sono causa di bug difficili da scovare. Il C# invece ci mette a disposizione un meccanismo più trasparente e sicuramente meno incline a bug.
I DELEGATE IN C SHARP I DELEGATE MULTICAST
Vediamo di chiarire alcuni aspetti prima di introdurre il codice per un multicast delegate. Tale tipo di delegate o meglio la variabile istanza del delegate viene inizializzata come già visto. Con l’operatore += si assegnano all’istanza creata a più metodi, al momento dell’invocazione i metodi verranno eseguiti in cascata. Vediamo due implicazioni da conoscere:
- Se il delegate restituisce un valore allora al momento dell’invocazione del multicast delegate verrà ritornato solo il valore dell’ultimo metodo eseguito. Quindi i delegate multicast vanno usati salvo rare eccezioni con il tipo restituito void.
- Se viene generata un’eccezione in uno dei metodi la catena di invocazione si interrompe.
using System;
namespace Delegate
{
public delegate void MyDelegate(int a, int b);
class Program
{
static void Main(string[] args)
{
MyDelegate md = Somma;
md += Differenza;
md+=Moltiplicazione;
md.Invoke(10,5);//SI PUO' USARE ANCHE IL METODO Invoke PER CHIAMARE IL METODO.
static void Somma(int arg1, int arg2)
{
Console.WriteLine($"Somma: {arg1 + arg2}");
}
static void Differenza(int arg1, int arg2)
{
Console.WriteLine($"Differenza: {arg1 - arg2}");
}
static void Moltiplicazione(int arg1, int arg2)
{
Console.WriteLine($"Moltiplicazione: {arg1 * arg2}");
}
}
}
}
I DELEGATE IN C SHARP I DELEGATE GENERICI
using System;
namespace Delegate
{
public delegate void MyDelegate<T>(T a, T b) where T:struct;
class Program
{
static void Main(string[] args)
{
MyDelegate<int> md1 = Somma;
MyDelegate<double> md2 = Differenza;
MyDelegate<float> md3 = Moltiplicazione;
md1.Invoke(12,7);
md2.Invoke(100.45,90.78);
md3.Invoke(12.8f, 13.4f);
static void Somma(int arg1, int arg2)
{
Console.WriteLine($"Somma: {arg1 + arg2}");
}
static void Differenza(double arg1, double arg2)
{
Console.WriteLine($"Differenza: {arg1 - arg2}");
}
static void Moltiplicazione(float arg1, float arg2)
{
Console.WriteLine($"Moltiplicazione: {arg1 * arg2}");
}
}
}
}
DELEGATE PREDEFINITI ACTION E FUNC
Il .NET Framework ci mette a disposizione due delegate predefiniti Action e Func. La differenza tra i due sta nel fatto che Action non restituisce valori, quindi il valore restituito è void e può accettare fino a 16 parametri di tipo. Il delegate Func viceversa lo usiamo quando abbiamo bisogno di un valore di ritorno. Vediamo come si presentano questi due delegate predefiniti.
public delegate void Action();
public delegate void Action(T arg);
public delegate void Action<T1,T2>(T1 arg1, T2 arg2);
public delegate TResult Func();
public delegate TResult Func<T1, TResult>(T1 arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
using System;
namespace Delegate
{
class Program
{
static void Main(string[] args)
{
Action<int,double> myAction = Somma;
myAction+=Differenza;
myAction+=Moltiplicazione;
myAction.Invoke(10,89.98);
static void Somma(int arg1, double arg2)
{
Console.WriteLine($"Somma: {arg1 + arg2}");
}
static void Differenza(int arg1, double arg2)
{
Console.WriteLine($"Differenza: {arg1 - arg2}");
}
static void Moltiplicazione(int arg1, double arg2)
{
Console.WriteLine($"Moltiplicazione: {arg1 * arg2}");
}
Func<double,double> MyFunc = RadiceQuadrata;
double result = MyFunc.Invoke(144);
Console.WriteLine(result);
static double RadiceQuadrata(double arg1)
{
return Math.Sqrt(arg1);
}
}
}
}
APPROFONDIMENTO SUI DELEGATE
In C#, un delegato è un tipo che rappresenta riferimenti a metodi con una particolare firma e tipo di ritorno. È simile a un puntatore a funzione in C++, ma è sicuro dal punto di vista del tipo e dell'ambiente. I delegati sono utilizzati per passare metodi come parametri a un'altra funzione. Questa funzionalità è particolarmente utile per la programmazione orientata agli eventi e per implementare callback.
Ecco una descrizione più dettagliata e un esempio di utilizzo dei delegati in C#:
Caratteristiche principali dei delegati:
1. Firma del Metodo: Un delegato può fare riferimento solo a metodi che abbiano una firma corrispondente (ossia, stesso tipo di ritorno e stessi parametri).
2. Multicast: I delegati possono essere concatenati insieme; cioè, possono fare riferimento a più metodi contemporaneamente. Quando viene invocato un delegato multicast, tutti i metodi ad esso associati vengono chiamati in sequenza.
3. Tipizzazione Sicura: I delegati sono sicuri dal punto di vista del tipo, il che significa che il compilatore controlla i tipi dei metodi assegnati ai delegati, prevenendo errori di tipo.
Definizione e Utilizzo di un Delegato:
Definizione di un Delegato
// Definizione di un delegato
public delegate void MyDelegate(string message);
Dichiarazione di Metodi Compatibili con il Delegato
// Metodo compatibile con il delegato
public void Method1(string message)
public void Method2(string message)
Assegnazione di Metodi al Delegato
// Creazione di un'istanza del delegato e assegnazione dei metodi
MyDelegate del = new MyDelegate(Method1);
del += Method2; // Aggiunta di un altro metodo al delegato (multicast)
// Invocazione del delegato
del("Hello, World!");
// Output:
// Method1: Hello, World!
// Method2: Hello, World!



Lascia un commento