C # - Delegati
I delegati C # sono simili ai puntatori alle funzioni, in C o C ++. UNdelegateè una variabile del tipo di riferimento che contiene il riferimento a un metodo. Il riferimento può essere modificato in fase di esecuzione.
I delegati sono usati specialmente per implementare eventi e metodi di callback. Tutti i delegati derivano implicitamente daSystem.Delegate classe.
Dichiarazione dei delegati
La dichiarazione del delegato determina i metodi a cui può fare riferimento il delegato. Un delegato può fare riferimento a un metodo che ha la stessa firma di quella del delegato.
Ad esempio, considera un delegato:
public delegate int MyDelegate (string s);
Il delegato precedente può essere utilizzato per fare riferimento a qualsiasi metodo che abbia un singolo parametro di stringa e restituisca una variabile di tipo int .
La sintassi per la dichiarazione del delegato è:
delegate <return type> <delegate-name> <parameter list>
Creazione di istanze dei delegati
Dopo aver dichiarato un tipo di delegato, è necessario creare un oggetto delegato con l'estensione new parola chiave ed essere associato a un metodo particolare. Durante la creazione di un delegato, l'argomento è passato anewl'espressione viene scritta in modo simile a una chiamata al metodo, ma senza gli argomenti del metodo. Ad esempio:
public delegate void printString(string s);
...
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
L'esempio seguente dimostra la dichiarazione, la creazione di istanze e l'uso di un delegato che può essere usato per fare riferimento a metodi che accettano un parametro intero e restituisce un valore intero.
using System;
delegate int NumberChanger(int n);
namespace DelegateAppl {
class TestDelegate {
static int num = 10;
public static int AddNum(int p) {
num += p;
return num;
}
public static int MultNum(int q) {
num *= q;
return num;
}
public static int getNum() {
return num;
}
static void Main(string[] args) {
//create delegate instances
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
//calling the methods using the delegate objects
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
Value of Num: 35
Value of Num: 175
Multicasting di un delegato
Gli oggetti delegato possono essere composti utilizzando l'operatore "+". Un delegato composto chiama i due delegati da cui è stato composto. È possibile comporre solo delegati dello stesso tipo. L'operatore "-" può essere utilizzato per rimuovere un delegato componente da un delegato composto.
Utilizzando questa proprietà dei delegati è possibile creare un elenco di chiamate di metodi che verranno chiamati quando viene richiamato un delegato. Questo è chiamatomulticastingdi un delegato. Il seguente programma dimostra il multicasting di un delegato:
using System;
delegate int NumberChanger(int n);
namespace DelegateAppl {
class TestDelegate {
static int num = 10;
public static int AddNum(int p) {
num += p;
return num;
}
public static int MultNum(int q) {
num *= q;
return num;
}
public static int getNum() {
return num;
}
static void Main(string[] args) {
//create delegate instances
NumberChanger nc;
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
nc = nc1;
nc += nc2;
//calling multicast
nc(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
Value of Num: 75
Utilizzo dei delegati
L'esempio seguente mostra l'uso di delegate. Il delegato printString può essere utilizzato per fare riferimento a un metodo che accetta una stringa come input e non restituisce nulla.
Usiamo questo delegato per chiamare due metodi, il primo stampa la stringa sulla console e il secondo la stampa su un file -
using System;
using System.IO;
namespace DelegateAppl {
class PrintString {
static FileStream fs;
static StreamWriter sw;
// delegate declaration
public delegate void printString(string s);
// this method prints to the console
public static void WriteToScreen(string str) {
Console.WriteLine("The String is: {0}", str);
}
//this method prints to a file
public static void WriteToFile(string s) {
fs = new FileStream("c:\\message.txt",
FileMode.Append, FileAccess.Write);
sw = new StreamWriter(fs);
sw.WriteLine(s);
sw.Flush();
sw.Close();
fs.Close();
}
// this method takes the delegate as parameter and uses it to
// call the methods as required
public static void sendString(printString ps) {
ps("Hello World");
}
static void Main(string[] args) {
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
sendString(ps1);
sendString(ps2);
Console.ReadKey();
}
}
}
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
The String is: Hello World