English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Se vogliamo passare una funzione come parametro come si fa? Come gestisce C# le funzioni di callback o gli eventi di gestione? La risposta è - delegato (Delegate). Un delegato (Delegate) è un tipo di variabile di riferimento che contiene un riferimento a un metodo. Il riferimento può essere modificato in tempo di esecuzione.
Il delegato èDefinire la firma del metodoil tipo di dati di riferimento. È possibile definire una variabile di delegato, come altri tipi di dati, che può riferirsi a qualsiasi metodo con la firma corrispondente al delegato.
Lavorare con i delegati implica tre passaggi:
Dichiarazione del delegato
Impostare il metodo di destinazione
Chiamata del delegato
È possibile dichiarare un delegato utilizzando la parola chiave delegate e la firma della funzione, come mostrato di seguito.
Sintassi del delegato
[modificatore di accesso] delegate [tipo di ritorno] [nome del delegato]([parametri])
Ecco una dichiarazione di un delegato chiamato MyDelegate.
public delegate void MyDelegate(string msg);
Sopra, abbiamo dichiarato un MyDelegate con
Dopo aver dichiarato il delegato, dobbiamo impostare il metodo di destinazione o l'espressione lambda. Possiamo farlo creando un oggetto del delegato utilizzando la parola chiave new e passando un metodo che ha la firma corrispondente al delegato.
public delegate void MyDelegate(string msg); // dichiarazione del delegato //impostare il metodo di destinazione MyDelegate del = new MyDelegate(MethodA); // o MyDelegate del = MethodA; // o espressione lambda MyDelegate del = (string msg) => Console.WriteLine(msg); // metodo di destinazione static void MethodA(string message) { Console.WriteLine(message); }
È possibile impostare il metodo di destinazione direttamente assegnando un metodo senza creare un oggetto del delegato, ad esempio MyDelegate del = MethodA.
Dopo aver impostato il metodo di destinazione, è possibile chiamare il delegato utilizzando il metodo Invoke() o l'operatore ().
del.Invoke("Hello World!"); //oppure del("Hello World!");
Ecco un esempio completo di delegato.
public delegate void MyDelegate(string msg); // Dichiarazione del delegato class Program { static void Main(string[] args) { MyDelegate del = ClassA.MethodA; del("Hello World"); del = ClassB.MethodB; del("Hello World"); del = (string msg) => Console.WriteLine("Chiamato espressione lambda: " + msg); del("Hello World"); } } class ClassA { static void MethodA(string message) { Console.WriteLine("Chiamato ClassA.MethodA() con parametro: " + message); } } class ClassB { static void MethodB(string message) { Console.WriteLine("Chiamato ClassB.MethodB() con parametro: " + message); } }
La seguente figura illustra il delegato.
Il metodo può avere un parametro di tipo delegato, come mostrato di seguito.
public delegate void MyDelegate(string msg); // Dichiarazione del delegato class Program { static void Main(string[] args) { MyDelegate del = ClassA.MethodA; InvokeDelegate(del); del = ClassB.MethodB; InvokeDelegate(del); del = (string msg) => Console.WriteLine("Chiamato espressione lambda: " + msg); InvokeDelegate(del); } static void InvokeDelegate(MyDelegate del) // Parametro di tipo MyDelegate { del("Hello World"); } } class ClassA { static void MethodA(string message) { Console.WriteLine("Chiamato ClassA.MethodA() con parametro: " + message); } } class ClassB { static void MethodB(string message) { Console.WriteLine("Chiamato ClassB.MethodB() con parametro: " + message); } }
In .NET, i tipi Func e Action sono delegati generici integrati, che dovrebbero essere utilizzati per i delegati più comuni, piuttosto che creare delegati personalizzati.
I delegati possono puntare a più metodi. Un delegato che punta a più metodi viene chiamato delegato multicast. Gli operatori “+” o “+=” aggiungono la funzione alla lista delle chiamate, mentre gli operatori “-” e “-=” la rimuovono.
public delegate void MyDelegate(string msg); // Dichiarazione del delegato class Program { static void Main(string[] args) { MyDelegate del1 = ClassA.MethodA; MyDelegate del2 = ClassB.MethodB; MyDelegate del = del1 + del2; // del1 + del2 del("Hello World"); MyDelegate del3 = (string msg) => Console.WriteLine("Chiamato espressione lambda: " + msg); del += del3; // del1 + del2 + del3 del("Hello World"); del = del - del2; // Rimuovi del2 del("Hello World"); del -= del1 // Rimuovi del1 del("Hello World"); } } class ClassA { static void MethodA(string message) { Console.WriteLine("Chiamato ClassA.MethodA() con parametro: " + message); } } class ClassB { static void MethodB(string message) { Console.WriteLine("Chiamato ClassB.MethodB() con parametro: " + message); } }
Gli operatori di somma e sottrazione lavorano sempre come parte dell'assegnazione: del1 += del2; è completamente equivalente a del1 = del1 + del2; la sottrazione è la stessa.
Se il delegato restituisce un valore, allora quando viene chiamato un delegato multicast, il valore dell'ultimo metodo di destinazione assegnato viene restituito.
public delegate int MyDelegate(); // dichiarazione del delegato class Program { static void Main(string[] args) { MyDelegate del1 = ClassA.MethodA; MyDelegate del2 = ClassB.MethodB; MyDelegate del = del1 + del2; Console.WriteLine(del()); // restituisce 200 } } class ClassA { static int MethodA() { return 100; } } class ClassB { static int MethodB() { return 200; } }
Puoi definire un delegato generico nello stesso modo di un delegato, ma puoi utilizzare i parametri di tipo generico o il tipo di ritorno. Quando si imposta il metodo di destinazione, è necessario specificare il tipo generico.
Ad esempio, guardiamo il delegato generico utilizzato per i parametri int e string.
public delegate T add<T>(T param1, T param2); // delegato generico class Program { static void Main(string[] args) { add<int> sum = Sum; Console.WriteLine(sum(10, 20)); add<string> con = Concat; Console.WriteLine(conct("Hello ", "World!!")); } public static int Sum(int val1, int val2) { return val1 + val2; } public static string Concat(string str1, string str2) { return str1 + str2; } }
I delegati sono anche utilizzati per dichiarare eventi e metodi anonimi.
Un delegato è un tipo di dati di riferimento che definisce una firma.
Un variabile di tipo delegato può riferirsi a qualsiasi metodo con lo stesso nome di firma del delegato.
Sintassi:[访问修饰符] delegato [return type] [delegate name]([参数])([access modifier] delegate [return type] [delegate name]([parameters]))
La firma del metodo di destinazione deve corrispondere alla firma del delegato.
Il delegato può essere chiamato come una funzione comune o tramite il metodo invoke().
È possibile assegnare più metodi a un delegato utilizzando l'operatore “+” o “+=” e rimuoverli utilizzando l'operatore “-” o “-=”; questo viene chiamato delegato multicast.
Se un delegato multicast restituisce un valore, restituisce il valore dell'ultimo metodo target assegnato.
Il delegato viene utilizzato per dichiarare eventi e metodi anonimi in C#.