Die Delegate-Klasse ist die Basisklasse für Delegatentypen. Nur das System oder Compiler können jedoch explizit von der Delegate-Klasse oder von der MulticastDelegate-Klasse ableiten. Es ist auch nicht zulässig, von einem Delegatentyp einen neuen Typ abzuleiten. Die Delegate-Klasse wird nicht als Delegatentyp betrachtet. Sie ist eine Klasse zum Ableiten von Delegatentypen.
Die meisten Programmiersprachen implementieren das Schlüsselwort delegate, und Compiler für diese Sprachen können von der MulticastDelegate-Klasse ableiten. Benutzer sollten daher das von der Sprache bereitgestellte Schlüsselwort delegate verwenden.
Hinweis |
|---|
Die Common Language Runtime stellt eine Invoke-Methode für jeden Delegattyp mit der gleichen Signatur wie der Delegat bereit. Sie müssen diese Methode nicht explizit von C#, Visual Basic oder Visual C++ aufrufen, da die Compiler sie automatisch aufrufen. Die Invoke-Methode ist in Reflektion nützlich, wenn Sie die Signatur vom Delegattyp suchen möchten. |
Die Common Language Runtime stellt jedem Delegattyp die BeginInvoke-Methode und die EndInvoke-Methode zur Verfügung, um den asynchronen Aufruf des Delegaten zu aktivieren. Weitere Informationen über diese Methoden finden Sie unter Asynchrones Aufrufen von synchronen Methoden.
Durch die Deklaration eines Delegatentyps wird ein Vertrag erstellt, der die Signatur einer oder mehrerer Methoden angibt. Ein Delegat ist eine Instanz eines Delegattyps, der auf Folgendes verweist:
Eine Instanzmethode eines Typs und ein Zielobjekt, das diesem Typ zugeordnet werden kann.
Eine Instanzmethode eines Typs, mit dem ausgeblendeten this-Parameter, der in der formalen Parameterliste verfügbar gemacht wird. Der Delegat wird als ein offener Instanzdelegat bezeichnet.
Eine statische Methode.
Eine statische Methode und ein Zielobjekt, das dem ersten Parameter der Methode zugeordnet werden kann. Der Delegat gilt als über seinem ersten Argument geschlossen.
Weitere Informationen zur Delegatbindung finden Sie in der CreateDelegate(Type, Object, MethodInfo, Boolean)-Methodenüberladung.
Hinweis |
|---|
In .NET Framework, Version 1.0 und 1.1, kann ein Delegat eine Methode nur darstellen, wenn die Signatur der Methode genau mit der durch den Delegattyp angegebenen Signatur übereinstimmt. Daher werden nur die unter Punkt 1 und 3 in der vorhergehenden Liste beschriebenen Elemente unterstützt, und beim ersten Aufzählungspunkt ist eine genaue Typübereinstimmung erforderlich. |
Wenn ein Delegat eine über seinem ersten Argument geschlossene Instanzmethode darstellt (der Normalfall), speichert der Delegat einen Verweis auf den Einstiegspunkt der Methode und einen Verweis auf ein Objekt, das als Ziel bezeichnet wird und von einem Typ ist, der dem durch die Methode definierten Typ zugeordnet werden kann. Wenn ein Delegat eine offene Instanzmethode darstellt, speichert er einen Verweis auf den Einstiegspunkt der Methode. Die Signatur des Delegaten muss in der formalen Parameterliste den ausgeblendeten this-Parameter enthalten. In diesem Fall verfügt der Delegat über keinen Verweis auf ein Zielobjekt, sodass das Zielobjekt beim Aufruf des Delegaten bereitgestellt werden muss.
Wenn ein Delegat eine statische Methode darstellt, wird im Delegaten ein Verweis auf den Einstiegspunkt der Methode gespeichert. Wenn ein Delegat eine über seinem ersten Element geschlossene statische Methode darstellt, speichert der Delegat einen Verweis auf den Einstiegspunkt der Methode und einen Verweis auf das Zielobjekt, das dem Typ des ersten Arguments der Methode zugeordnet werden kann. Beim Aufruf des Delegaten empfängt das erste Argument der statischen Methode das Zielobjekt.
Die Aufrufliste eines Delegaten ist eine geordnete Menge von Delegaten, bei der jedes Element der Liste genau eine der vom Delegaten dargestellten Methoden aufruft. Eine Aufrufliste kann Methoden mehrfach enthalten. Während eines Aufrufs werden die Methoden in der Reihenfolge der Aufrufliste aufgerufen. Ein Delegat versucht, jede Methode in seiner Aufrufliste aufzurufen. Duplikate werden einmal für jedes Vorkommen in der Aufrufliste aufgerufen. Delegaten sind unveränderlich. Die Aufrufliste eines Delegaten kann nach dem Erstellen nicht geändert werden.
Delegaten werden als Multicast- oder kombinierbare Delegaten bezeichnet, weil ein Delegat eine oder mehr Methoden aufrufen kann und in Kombinationsvorgängen verwendet werden kann.
Durch Kombinationsoperationen wie Combine und Remove werden vorhandene Delegaten nicht geändert. Eine Kombinationsoperation gibt stattdessen einen neuen Delegaten zurück, der die Ergebnisse der Operation, einen nicht geänderten Delegaten oder null enthält. Eine Kombinationsoperation gibt null zurück, wenn das Ergebnis der Operation ein Delegat ist, der nicht auf mindestens eine Methode verweist. Eine Kombinationsoperation gibt einen nicht geänderten Delegaten zurück, wenn die angeforderte Operation keine Auswirkungen hat.
Hinweis |
|---|
Verwaltete Sprachen verwenden die Combine-Methode und Remove-Methode, um Stellvertreteroperationen zu implementieren. Zu den Beispielen gehören u.a. AddHandler-Anweisungen und RemoveHandler-Anweisungen in Visual Basic sowie die Operatoren += and -= für Delegattypen in C#. |
Beginnend bei .NET Framework, Version 4 können die generischen Delegattypen verschiedene Typparameter aufweisen. Kovariante Typparameter können als Parametertypen des Delegaten verwendet ewrden, und ein kovarianter Typparameter kann als Rückgabetyp verwendet werden. Diese Funktion lässt generische Delegattypen zu, die aus der gleichen generischen Typdefinition erstellt werden, um zuweisungskompatibel zu sein, wenn ihre Typargumente Verweistypen mit einer Vererbungsbeziehung sind, wie in Kovarianz und Kontravarianz in Generika erklärt.
Hinweis |
|---|
Generische Delegaten, die wegen der Varianz zuweisungskompatibel sind, sind nicht notwendigerweise kombinierbar. Um kombinierbar zu sein, müssen die Typen genau zusammenpassen. Angenommen, die Klasse Derived ist von der Basisklasse Base abgeleitet. Ein Delegat vom Typ Action<Base> (Action(Of Base) in Visual Basic) kann einer Variablen vom Typ Action<Derived> zugewiesen werden, die beiden Delegaten können jedoch nicht kombiniert werden, da die Typen nicht genau übereinstimmen. |
Wenn die aufgerufene Methode eine Ausnahme auslöst, wird die Ausführung der Methode abgebrochen und die Ausnahme an den Aufrufer des Delegaten übergeben. Weitere Methoden in der Aufrufliste werden nicht aufgerufen. Wenn der Aufrufer die Ausnahme abfängt, ändert sich dieses Verhalten nicht.
Wenn die Signatur der vom Delegaten aufgerufenen Methoden einen Rückgabewert enthält, gibt der Delegat den Rückgabewert des letzten Elements der Aufrufliste zurück. Wenn die Signatur einen als Verweis übergebenen Parameter enthält, ist der Endwert des Parameters das Ergebnis der Ausführung aller Methoden in der Reihenfolge der Aufrufliste und der Aktualisierung des Parameterwerts.
Ein Funktionszeiger kommt einem Delegaten in C oder C++ am nächsten. Ein Delegat kann eine statische Methode oder eine Instanzmethode darstellen. Wenn der Delegat eine Instanzmethode darstellt, speichert dieser nicht nur einen Verweis auf den Einstiegspunkt der Methode, sondern außerdem einen Verweis auf die Klasseninstanz. Im Gegensatz zu Funktionszeigern sind Delegaten objektorientiert und typsicher.