Delegate (CLI)
# Delegate (CLI)

Ein Delegat ist eine Form des Typsicherheitsfunktionszeigers, der von der Common Language Infrastructure (CLI) verwendet wird. Delegates legen eine Methode zum Aufrufen und optional ein Objekt für den Methodenaufruf fest. Delegates werden unter anderem eingesetzt, um Callbacks und Event-Listener zu implementieren. Ein Delegatobjekt kapselt einen Verweis auf eine Methode. Das Delegatobjekt kann dann an ein Stück Code übergeben werden, der die referenzierte Methode aufrufen kann, ohne zur Kompilierzeit wissen zu müssen, welche Methode aufgerufen wird.
Ein Multicast-Delegat ist ein Delegat, das auf mehrere Methoden verweist. Die Multicast-Delegierung ist ein Mechanismus, der Funktionalität bereitstellt, um mehr als eine Methode auszuführen. Es gibt eine Liste von Delegates, die intern gepflegt werden. Wird nun der Multicast-Delegat aufgerufen, wird diese Liste der Delegates ausgeführt.
In C# werden häufig Delegates verwendet, um Rückrufe in der ereignisgesteuerten Programmierung zu implementieren. Beispielsweise kann ein Delegat verwendet werden, um anzugeben, welche Methode aufgerufen werden soll, wenn der Benutzer auf eine Schaltfläche klickt. Delegates erlauben dem Programmierer, mehrere Methoden vom Eintreten eine Ereignisses zu benachrichtigen.

## C#-Codebeispiel

Der Code unten deklariert ein delegate-Typ, heißt SendMessageDelegate, nimmt als Parameter eine Message und gibt ein void zurück:
Code, um eine Methode zu definieren, die ein instantiiertes Delegat als Argument annimmt:
Die implementierte Methode, die ausgeführt wird, wenn das Delegat aufgerufen wird:
Code, um die SendMessageDelegate-Methode aufzurufen, wobei ein instantiiertes Delegat als Argument übergeben wird:

### Delegates (C#)

Eine Delegatvariable ruft die zugehörige Methode auf und wird selber wie folgt aufgerufen:
Delegatvariablen sind First-Class-Objekts der Form new DelegateType(obj.Method) und können jeder passenden Methode oder dem Wert null zugeordnet werden. Sie speichern eine Methode und ihren Empfänger ohne Parameter:
Das Objekt funnyObj kann this sein und weggelassen werden. Wenn die Methode static ist, sollte sie nicht das Objekt sein (auch als Instanz in anderen Sprachen bezeichnet), sondern die Klasse selbst. Es sollte nicht abstract sein, sondern könnte new, override oder virtuel.
Um eine Methode erfolgreich mit einem Delegat aufzurufen, muss die Methodensignatur dem DelegateType mit derselben Anzahl gleichartiger Parameter (ref, out, value) und demselben Typ (einschließlich Rückgabetyp) entsprechen.

### Multicast-Delegates (C#)

Eine Delegat-Variable kann mehrere Werte gleichzeitig enthalten:
Wenn der Multicast-Delegat eine Funktion ist oder kein Parameter out hat, wird der Parameter des letzten Aufrufs zurückgegeben.

## Technische Details

Obwohl interne Implementierungen variieren können, können Delegate-Instanzen als Tupel eines Objekts und eines Methodenzeigers und eines Verweises (möglicherweise null) auf einen anderen Delegaten gedacht werden. Daher ist ein Verweis auf einen Delegierten möglicherweise ein Hinweis auf mehrere Delegierte. Wenn der erste Delegat beendet ist, wenn seine Kettenreferenz nicht null ist, wird der nächste aufgerufen, und so weiter, bis die Liste vollständig ist. Dieses Muster ermöglicht es einem Ereignis, Overhead-Skalierung leicht von dem eines einzelnen Verweises bis zum Versand zu einer Liste von Delegaten zu haben, und ist weit verbreitet in der CLI verwendet.

## Leistung

Die Leistung von Delegates war viel langsamer als eine virtuelle oder Interface-Methode aufzurufen (ein 1/6 bis 1/8 Mal so schnell in Microsoft 2003 Benchmarks), aber seit dem .NET 2.0 CLR im Jahr 2005 ist es ungefähr gleich schnell wie Interface-Aufrufe. D.h., dass es einen kleinen zusätzlichen Overhead im Vergleich zu direkten Methodenaufrufen gibt.
Es gibt sehr strenge Regeln für den Bau von delegierten Klassen.