Condividi tramite


Delegati nel sistema di tipi comuni

Aggiornamento: novembre 2007

In runtime sono supportati tipi di riferimento detti delegati, il cui scopo è simile a quello dei puntatori a funzione in C++. Diversamente dai puntatori a funzione, i delegati sono sicuri, verificabili e indipendenti dai tipi. Un tipo di delegato può rappresentare qualsiasi metodo con una firma compatibile. Mentre i puntatori a funzione possono rappresentare solo funzioni statiche, un delegato può rappresentare sia metodi statici che di istanza. I delegati vengono utilizzati per i gestori eventi e le funzioni di callback in .NET Framework.

Nota:

Poiché Common Language Runtime non supporta la serializzazione di metodi globali, non è possibile utilizzare i delegati per eseguire metodi globali in altri domini applicazione.

Tutti i delegati ereditano da MulticastDelegate, che eredita da Delegate. I linguaggi C#, Visual Basic e C++ non consentono l'ereditarietà da questi tipi ma forniscono parole chiave per la dichiarazione dei delegati.

Oltre ai metodi ereditati, Common Language Runtime fornisce due metodi speciali per i tipi delegati: BeginInvoke e EndInvoke. Per ulteriori informazioni su questi metodi, vedere Chiamata asincrona dei metodi sincroni.

Dal momento che i delegati ereditano da MulticastDelegate, un delegato presenta un elenco chiamate, ovvero un elenco di metodi rappresentati dal delegato che vengono eseguiti quando il delegato viene chiamato. Tutti i metodi dell'elenco ricevono gli argomenti forniti quando viene chiamato il delegato.

Nota:

Il valore restituito non è definito per un delegato il cui elenco chiamate contiene più metodi, anche se il delegato dispone di un tipo restituito.

Creazione e utilizzo dei delegati

In molti casi, ad esempio nel caso di metodi di callback, un delegato rappresenta un solo metodo e le uniche azioni che è necessario intraprendere sono la creazione e il richiamo del delegato.

Per i delegati che rappresentano più metodi, .NET Framework fornisce metodi delle classi di delegati Delegate e MulticastDelegate per supportare operazioni quali l'aggiunta di un metodo a un elenco chiamate di un delegato (il metodo Delegate.Combine), la rimozione di un metodo (il metodo Delegate.Remove) e il recupero dell'elenco chiamate (il metodo Delegate.GetInvocationList).

Nota:

Non è necessario utilizzare questi metodi per i delegati dei gestori eventi nei linguaggi C#, C++ e Visual Basic, in quanto in tali linguaggi è disponibile la sintassi per l'aggiunta e la rimozione dei gestori eventi.

Delegati statici chiusi o delegati di istanza aperti

I delegati possono rappresentare metodi static (Shared in Visual Basic) o di istanza. Quando un delegato rappresenta un metodo di istanza, l'istanza è generalmente associata al delegato insieme al metodo. Nell'elenco chiamate di un delegato di gestore eventi, ad esempio, potrebbero essere presenti tre metodi di istanza, ognuno dei quali con un riferimento all'oggetto al quale appartiene il metodo.

In .NET Framework versione 2.0 è anche possibile creare un delegato aperto per un metodo di istanza. Un metodo di istanza presenta un parametro di istanza implicito (rappresentato da this in C# o Me in Visual Basic) e può essere rappresentato da un tipo di delegato che espone questo parametro nascosto. In altri termini, il tipo di delegato deve presentare un parametro aggiuntivo all'inizio dell'elenco di parametri formali che deve essere dello stesso tipo della classe a cui appartiene il metodo. È supportato anche lo scenario opposto, pertanto è possibile associare il primo argomento di un metodo statico.

Nota:

La creazione di delegati di istanza aperti e di delegati statici chiusi non è supportata direttamente da Visual Basic, C++ o C# per i costruttori di delegati. Utilizzare, in alternativa, uno degli overload di metodi Delegate.CreateDelegate che specifichi gli oggetti MethodInfo, ad esempio Delegate.CreateDelegate(Type, Object, MethodInfo, Boolean).

Regole flessibili per l'associazione di delegati

In .NET Framework versione 2.0 i tipi di parametri e il tipo restituito di un delegato devono essere compatibili con i tipi di parametri e il tipo restituito del metodo rappresentato dal delegato. Non è necessaria un'esatta corrispondenza tra i tipi.

Nota:

Questa necessità si verifica invece in .NET Framework versioni 1.0 e 1.1.

Un parametro di un delegato è compatibile con il parametro di un metodo corrispondente se il tipo del parametro del delegato è più restrittivo rispetto al tipo del parametro del metodo. In questo modo si garantisce che un argomento passato al delegato possa essere passato in modo sicuro al metodo.

Analogamente, il tipo restituito di un delegato è compatibile con il tipo restituito di un metodo se il tipo restituito del metodo è più restrittivo rispetto al tipo restituito del delegato. In questo modo si garantisce la possibilità di eseguire in modo sicuro il cast del valore restituito del metodo nel tipo restituito del delegato.

Un delegato con un parametro del tipo Hashtable e un tipo restituitoObject può, ad esempio, rappresentare un metodo con un parametro del tipo Object e un valore restituito del tipo Hashtable.

Per ulteriori informazioni e un esempio di codice, vedere Delegate.CreateDelegate(Type, Object, MethodInfo).

Delegati e chiamate di metodo asincrone

Ogni delegato è dotato di un metodo BeginInvoke che consente di chiamare il delegato in modo asincrono, nonché di un metodo EndInvoke che successivamente pulisce le risorse. Tali metodi vengono generati automaticamente per ciascun tipo di delegato. Quando un delegato viene chiamato mediante il metodo BeginInvoke, il metodo rappresentato dal delegato viene eseguito su un thread che appartiene a ThreadPool.

Per ulteriori informazioni e un esempio di codice, vedere Programmazione asincrona tramite delegati.

Vedere anche

Concetti

Utilizzo degli eventi

Eventi e delegati

Riferimenti

System.Delegate

System.EventHandler

Altre risorse

Sistema di tipi comuni

Programmazione asincrona tramite delegati