C # conosce due termini delegate
e event
. Cominciamo con il primo.
Delegare
A delegate
è un riferimento a un metodo. Proprio come puoi creare un riferimento a un'istanza:
MyClass instance = myFactory.GetInstance();
È possibile utilizzare un delegato per creare un riferimento a un metodo:
Action myMethod = myFactory.GetInstance;
Ora che hai questo riferimento a un metodo, puoi chiamare il metodo tramite il riferimento:
MyClass instance = myMethod();
Ma perché dovresti? Puoi anche semplicemente chiamare myFactory.GetInstance()
direttamente. In questo caso puoi. Tuttavia, ci sono molti casi in cui pensare a dove non si desidera che il resto dell'applicazione sia a conoscenza myFactory
o che chiami myFactory.GetInstance()
direttamente.
Un più ovvia è che se si vuole essere in grado di sostituire myFactory.GetInstance()
in myOfflineFakeFactory.GetInstance()
da un posto centrale (aka metodo factory modello ).
Modello del metodo di fabbrica
Quindi, se hai una TheOtherClass
classe e devi usarla myFactory.GetInstance()
, ecco come apparirà il codice senza delegati (dovrai far TheOtherClass
sapere il tipo del tuo myFactory
):
TheOtherClass toc;
//...
toc.SetFactory(myFactory);
class TheOtherClass
{
public void SetFactory(MyFactory factory)
{
// set here
}
}
Se utilizzi delegati, non devi esporre il tipo di mia fabbrica:
TheOtherClass toc;
//...
Action factoryMethod = myFactory.GetInstance;
toc.SetFactoryMethod(factoryMethod);
class TheOtherClass
{
public void SetFactoryMethod(Action factoryMethod)
{
// set here
}
}
Pertanto, puoi assegnare un delegato a un'altra classe da utilizzare, senza esporre il tuo tipo a loro. L'unica cosa che stai esponendo è la firma del tuo metodo (quanti parametri hai e simili).
"Firma del mio metodo", dove l'ho già sentito? O sì, interfacce !!! le interfacce descrivono la firma di un'intera classe. Pensa ai delegati come a descrivere la firma di un solo metodo!
Un'altra grande differenza tra un'interfaccia e un delegato è che quando scrivi la tua classe, non devi dire a C # "questo metodo implementa quel tipo di delegato". Con le interfacce, devi dire "questa classe implementa quel tipo di interfaccia".
Inoltre, un riferimento delegato può (con alcune restrizioni, vedere di seguito) fare riferimento a più metodi (chiamati MulticastDelegate
). Ciò significa che quando si chiama il delegato, verranno eseguiti più metodi esplicitamente collegati. Un riferimento a un oggetto può sempre fare riferimento solo a un oggetto.
Le restrizioni per a MulticastDelegate
sono che la firma (metodo / delegato) non deve avere alcun valore restituito ( void
) e le parole chiave out
e ref
non viene utilizzata nella firma. Ovviamente, non puoi chiamare due metodi che restituiscono un numero e aspettarti che restituiscano lo stesso numero. Una volta che la firma è conforme, il delegato è automaticamente a MulticastDelegate
.
Evento
Gli eventi sono solo proprietà (come get; set; proprietà nei campi istanza) che espongono la sottoscrizione al delegato da altri oggetti. Queste proprietà, tuttavia, non supportano get; set ;. Al contrario, supportano add; rimuovere;
Quindi puoi avere:
Action myField;
public event Action MyProperty
{
add { myField += value; }
remove { myField -= value; }
}
Utilizzo nell'interfaccia utente (WinForms, WPF, UWP e così via)
Quindi, ora sappiamo che un delegato è un riferimento a un metodo e che possiamo avere un evento per far sapere al mondo che possono darci i loro metodi per essere referenziati dal nostro delegato, e noi siamo un pulsante dell'interfaccia utente, quindi: noi può chiedere a chiunque sia interessato a sapere se sono stato cliccato, di registrare il nostro metodo con noi (tramite l'evento che abbiamo esposto). Possiamo usare tutti quei metodi che ci sono stati dati e fare riferimento a loro dal nostro delegato. E poi, aspetteremo e aspetteremo ... fino a quando un utente arriva e fa clic su quel pulsante, quindi avremo abbastanza motivi per invocare il delegato. E poiché il delegato fa riferimento a tutti quei metodi che ci vengono forniti, tutti questi metodi verranno invocati. Non sappiamo cosa fanno questi metodi, né sappiamo quale classe implementa quei metodi. Ci interessa solo che qualcuno fosse interessato a fare clic su di noi,
Giava
Lingue come Java non hanno delegati. Usano invece interfacce. Il modo in cui lo fanno è chiedere a chiunque sia interessato a "essere cliccato", di implementare una certa interfaccia (con un certo metodo che possiamo chiamare), quindi fornirci l'intera istanza che implementa l'interfaccia. Manteniamo un elenco di tutti gli oggetti che implementano questa interfaccia e possiamo chiamare il loro "certo metodo che possiamo chiamare" ogni volta che facciamo clic.