Delegaten im allgemeinen Typsystem

Aktualisiert: November 2007

Die Laufzeit unterstützt Verweistypen, so genannte Delegaten, die einen ähnlichen Zweck erfüllen wie Funktionszeiger in C++. Im Gegensatz zu Funktionszeigern sind Delegaten sicher, überprüfbar und typsicher. Ein Delegattyp kann jede Methode mit einer kompatiblen Signatur darstellen. Während Funktionszeiger lediglich statische Funktionen darstellen können, ist ein Delegat in der Lage, sowohl statische als auch Instanzenmethoden darzustellen. Delegaten werden für Ereignishandler und Rückruffunktionen in .NET Framework verwendet.

Hinweis:

Die Common Language Runtime unterstützt keine Serialisierung der globalen Methoden. Daher können Delegaten nicht verwendet werden, um globale Methoden in anderen Anwendungsdomänen auszuführen.

Alle Delegaten erben von MulticastDelegate, welcher von Delegate erbt. In den Programmiersprachen C#, Visual Basic und C++ ist eine Vererbung von diesen Typen nicht zulässig. Stattdessen stehen Schlüsselwörter zum Deklarieren von Delegaten zur Verfügung.

Zusätzlich zu geerbten Methoden stellt die Common Language Runtime zwei spezielle Methoden für Delegattypen bereit: BeginInvoke und EndInvoke. Weitere Informationen zu diesen Methoden finden Sie unter Asynchrones Aufrufen von synchronen Methoden.

Da Delegaten von MulticastDelegate erben, verfügt ein Delegat über eine Aufrufliste. Dabei handelt es sich um eine Liste der Methoden, die dieser Delegat darstellt und die beim Aufrufen des Delegaten ausgeführt werden. Alle Methoden in der Liste empfangen die beim Aufrufen des Delegaten angegebenen Argumente.

Hinweis:

Der Rückgabewert von Delegaten mit mehr als einer Methode in der Aufrufliste ist nicht definiert, selbst wenn diese über einen Rückgabetyp verfügen.

Erstellen und Verwenden von Delegaten

In vielen Fällen (z. B. bei Rückrufmethoden) stellt ein Delegat nur eine Methode dar. Sie müssen den Delegaten lediglich erstellen und aufrufen.

Für Delegaten, die mehrere Methoden darstellen, enthält .NET Framework Methoden der Delegate-Delegatklasse und MulticastDelegate-Delegatklasse, um verschiedene Vorgänge zu unterstützen. Dazu gehören das Hinzufügen einer Methode zur Aufrufliste eines Delegaten (die Delegate.Combine-Methode), das Entfernen einer Methode (die Delegate.Remove-Methode) und das Abrufen der Aufrufliste (die Delegate.GetInvocationList-Methode).

Hinweis:

Es ist in C#, C++ und Visual Basic nicht erforderlich, diese Methoden für Ereignishandler-Delegaten einzusetzen, da in diesen Programmiersprachen Syntax zum Hinzufügen und Entfernen von Ereignishandlern bereitsteht.

Geschlossene statische Delegaten und offene Instanzendelegaten

Delegaten können static- (Shared in Visual Basic) oder Instanzenmethoden darstellen. Wenn ein Delegat eine Instanzenmethode darstellt, wird die Instanz gewöhnlich zusammen mit der Methode an den Delegaten gebunden. Ein Ereignishandler-Delegat verfügt in seiner Aufrufliste beispielsweise über drei Instanzenmethoden. Jede dieser Methoden enthält einen Verweis auf das Objekt, zu dem die Methode gehört.

In .NET Framework, Version 2.0, ist es auch möglich, für eine Instanzenmethode einen offenen Delegaten zu erstellen. Eine Instanzenmethode hat einen impliziten Instanzparameter (in C# dargestellt durch this bzw. in Visual Basic durch Me) und kann durch einen Delegattyp dargestellt werden, der diesen ausgeblendeten Parameter verfügbar macht. Das heißt, der Delegattyp muss am Anfang der Liste formaler Parameter einen zusätzlichen Parameter aufweisen, der denselben Typ hat wie die Klasse, zu der die Methode gehört. Der umgekehrte Fall wird ebenfalls unterstützt, sodass es möglich ist, das erste Argument einer statischen Methode zu binden.

Hinweis:

Die Erstellung offener Instanzendelegaten und geschlossener statischer Delegaten für Delegatkonstruktoren wird von Visual Basic, C++ oder C# nicht direkt unterstützt. Verwenden Sie stattdessen eine der Überladungen der Delegate.CreateDelegate-Methode, mit der MethodInfo-Objekte angegeben werden, z. B. Delegate.CreateDelegate(Type, Object, MethodInfo, Boolean).

Weniger strenge Regeln für die Delegatbindung

Die Parametertypen und der Rückgabetyp eines Delegaten müssen in .NET Framework, Version 2, mit den Parametertypen und dem Rückgabetyp der Methode kompatibel sein, die der Delegat darstellt. Die Typen müssen nicht exakt übereinstimmen.

Hinweis:

In .NET Framework, Versionen 1.0 und 1.1 müssen die Typen genau übereinstimmen.

Ein Parameter eines Delegaten ist mit dem entsprechenden Parameter einer Methode kompatibel, wenn der Typ des Delegatenparameters restriktiver ist als der Methodenparameter, da so gewährleistet ist, dass ein an den Delegaten übergebenes Argument problemlos an die Methode weitergeleitet werden kann.

Ebenso ist der Rückgabetyp eines Delegaten kompatibel mit dem Rückgabetyp einer Methode, wenn der Rückgabetyp der Methode restriktiver ist als der Rückgabetyp des Delegaten, da so gewährleistet ist, dass der Rückgabewert der Methode problemlos in den Rückgabetyp des Delegaten umgewandelt werden kann.

Beispielsweise kann ein Delegat mit dem Parametertyp Hashtable und dem Rückgabetyp Object eine Methode mit dem Parametertyp Object und dem Rückgabetyp Hashtable darstellen.

Weitere Informationen und Beispielcode finden Sie unter Delegate.CreateDelegate(Type, Object, MethodInfo).

Delegaten und asynchrone Methodenaufrufe

Jeder Delegat verfügt über eine BeginInvoke-Methode, mit der dieser Delegat asynchron aufgerufen werden kann, und eine EndInvoke-Methode, mit der anschließend die Ressourcen bereinigt werden. Diese Methoden werden für jeden Delegattyp automatisch generiert. Beim Aufrufen eines Delegaten mithilfe der BeginInvoke-Methode wird die durch den Delegaten dargestellte Methode in einem Thread aus dem ThreadPool ausgeführt.

Weitere Informationen und Beispielcode finden Sie unter Asynchrone Programmierung mithilfe von Delegaten.

Siehe auch

Konzepte

Behandeln von Ereignissen

Ereignisse und Delegaten

Referenz

System.Delegate

System.EventHandler

Weitere Ressourcen

Allgemeines Typsystem

Asynchrone Programmierung mithilfe von Delegaten