C # – Come posso “sovraccaricare” un delegato?

In primo luogo, stavo leggendo alcuni forum e l’aiuto in MSDN e tutti dicono che un delegato non può essere sovraccaricato.

Ora, voglio avere qualcosa di simile a questo:

public delegate void OneDelegate(); public delegate void OneDelegate(params object[] a); public void DoNothing(params object[] a) {} public void DoSomething() { /* do something */ } private OneDelegate someFunction; someFunction = new OneDelegate(DoSomething); someFunction = new OneDelegate(DoNothing); 

Quindi, come sai, NON puoi farlo, perché OneDelegate si riferisce solo al primo e non al secondo. Ma c’è un modo per farlo? o qualcosa di simile?

PS1: voglio avere un numero qualsiasi di dichiarazioni OneDelegate, non solo uno o due.

Immagina per un momento che fosse ansible. Supponiamo che potrei avere un delegato sovraccarico:

 public delegate void OneDelegate(int i); public delegate void OneDelegate(string s); 

Ora immagino di dichiarare una variabile di questo tipo e quindi di assegnargli una funzione, ad esempio:

 OneDelegate myDelegate = StringMethod; 

dove StringMethod è dichiarato così:

 public void StringMethod(string s) { Console.WriteLine(s); } 

Ora si passa myDelegate ad un altro codice e questo codice lo fa:

 myDelegate(47); 

Cosa ti aspetti che accada in questo caso? Come può il runtime chiamare StringMethod() con un argomento intero?

Se vuoi davvero un delegato che possa prendere qualsiasi insieme di parametri , allora l’unica opzione è quella di avere uno con un array params object[] :

 public delegate void OneDelegate(params object[] parameters); 

Ma poi dovrai assegnargli una funzione che possa effettivamente gestire qualsiasi array di oggetti, ad esempio:

 public void MyMethod(params object[] parameters) { if (parameters == null || parameters.Length == 0) throw new ArgumentException("No parameters specified."); if (parameters.Length > 1) throw new ArgumentException("Too many parameters specified."); if (parameters[0] is int) IntMethod((int) parameters[0]); else if (parameters[0] is string) StringMethod((string) parameters[0]); else throw new ArgumentException("Unsupported parameter type."); } 

Come puoi vedere, questo diventa molto veloce. Pertanto, ti presento che se hai bisogno di un tale delegato, probabilmente hai fatto un errore da qualche parte nel tuo progetto architettonico. Identifica questo difetto e fissa il progetto prima di procedere con l’implementazione, altrimenti subirà la manutenzione del tuo codice.

La class Action “fa questo”. È un delegato con modelli, quindi puoi avere un delegato come questo:

 public delegate void D(params T[] arg); func() { D d1; } 

Questo è probabilmente il più vicino ansible, ovvero è necessario un tipo di modello come parametro.

Modifica: in base ai commenti, suppongo che tu sia dopo aver passato un delegato a un’altra funzione. Puoi realizzarlo passando anche gli argomenti. Sfortunatamente non puoi farlo senza l’uso di un parametro params per fire .

 public void bar() { D d = ...; fire(d, "first", "second"); fire(d); // also works } public void fire(D f, params T[] args) { f(args); }