Verwenden von Delegaten (C#-Programmierhandbuch)Using Delegates (C# Programming Guide)

Ein Delegat ist ein Typ, der ähnlich einem Funktionszeiger in C und C++ eine Methode sicher kapselt.A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Im Gegensatz zu C-Funktionszeigern sind Delegate objektorientiert, typsicher und sicher.Unlike C function pointers, delegates are object-oriented, type safe, and secure. Der Typ eines Delegaten wird durch den Namen des Delegaten definiert.The type of a delegate is defined by the name of the delegate. Im folgenden Beispiel wird ein Delegat mit dem Namen Del deklariert, der eine Methode kapseln kann, die eine Zeichenfolge als Argument übernimmt und void zurückgibt:The following example declares a delegate named Del that can encapsulate a method that takes a string as an argument and returns void:

public delegate void Del(string message);

Ein Delegatobjekt wird normalerweise durch Angabe des Namens der Methode, die der Delegat umschließt, oder mit einer anonymen Methode erstellt.A delegate object is normally constructed by providing the name of the method the delegate will wrap, or with an anonymous Method. Sobald ein Delegat instanziiert ist, wird vom Delegaten ein Methodenaufruf an den Delegaten an diese Methode übergeben.Once a delegate is instantiated, a method call made to the delegate will be passed by the delegate to that method. Die vom Aufrufer an den Delegaten übergebenen Parameter werden an die Methode übergeben, und der Rückgabewert von der Methode wird ggf. durch den Delegaten an den Aufrufer zurückgegeben.The parameters passed to the delegate by the caller are passed to the method, and the return value, if any, from the method is returned to the caller by the delegate. Dies wird als Aufrufen des Delegaten bezeichnet.This is known as invoking the delegate. Ein instanziierter Delegat kann wie die eingeschlossene Methode selbst aufgerufen werden.An instantiated delegate can be invoked as if it were the wrapped method itself. Beispiel:For example:

// Create a method for a delegate.
public static void DelegateMethod(string message)
{
    System.Console.WriteLine(message);
}
// Instantiate the delegate.
Del handler = DelegateMethod;

// Call the delegate.
handler("Hello World");

Delegattypen werden von der Delegate-Klasse im .NET Framework abgeleitet.Delegate types are derived from the Delegate class in the .NET Framework. Delegattypen sind versiegelt – von Ihnen kann nicht abgeleitet werden – und es ist nicht möglich benutzerdefinierte Klassen von Delegate abzuleiten.Delegate types are sealed—they cannot be derived from— and it is not possible to derive custom classes from Delegate. Da der instanziierte Delegat ein Objekt ist, kann er als Parameter übergeben oder einer Eigenschaft zugewiesen werden.Because the instantiated delegate is an object, it can be passed as a parameter, or assigned to a property. Dies ermöglicht es einer Methode, einen Delegaten als Parameter zu akzeptieren und den Delegaten zu einem späteren Zeitpunkt aufzurufen.This allows a method to accept a delegate as a parameter, and call the delegate at some later time. Dies wird als asynchroner Rückruf bezeichnet und ist eine häufig verwendete Methode, um einen Aufrufer darüber zu benachrichtigen, dass ein langer Prozess abgeschlossen wurde.This is known as an asynchronous callback, and is a common method of notifying a caller when a long process has completed. Wenn ein Delegat auf diese Weise verwendet wird, benötigt der Code, der den Delegaten verwendet, keine Kenntnisse über die Implementierung der verwendeten Methode.When a delegate is used in this fashion, the code using the delegate does not need any knowledge of the implementation of the method being used. Die Funktion ähnelt den bereitgestellten Kapselungsschnittstellen.The functionality is similar to the encapsulation interfaces provide.

Ein weiterer häufiger Einsatzbereich von Rückrufen ist die Definition einer benutzerdefinierten Vergleichsmethode und die Übergabe dieses Delegaten an eine Sortiermethode.Another common use of callbacks is defining a custom comparison method and passing that delegate to a sort method. Dadurch kann der Code des Aufrufers Teil des Sortieralgorithmus werden.It allows the caller's code to become part of the sort algorithm. Im folgenden Beispiel wird der Typ Del als Parameter verwendet:The following example method uses the Del type as a parameter:

public void MethodWithCallback(int param1, int param2, Del callback)
{
    callback("The number is: " + (param1 + param2).ToString());
}

Sie können anschließend den oben erstellten Delegaten an diese Methode übergeben:You can then pass the delegate created above to that method:

MethodWithCallback(1, 2, handler);

woraufhin die folgende Ausgabe auf der Konsole angezeigt wird:and receive the following output to the console:

The number is: 3

Wenn Sie den Delegaten als Abstraktion verwenden, muss MethodWithCallback die Konsole nicht direkt aufrufen, d. h., bei der Entwicklung muss keine Konsole berücksichtigt werden.Using the delegate as an abstraction, MethodWithCallback does not need to call the console directly—it does not have to be designed with a console in mind. MethodWithCallback bereitet einfach eine Zeichenfolge vor und übergibt sie an eine andere Methode.What MethodWithCallback does is simply prepare a string and pass the string to another method. Dies ist besonders leistungsstark, da eine delegierte Methode eine beliebige Anzahl Parameter verwenden kann.This is especially powerful since a delegated method can use any number of parameters.

Wenn ein Delegat erstellt wurde, um eine Instanzenmethode zu umschließen, verweist der Delegat sowohl auf die Instanz als auch auf die Methode.When a delegate is constructed to wrap an instance method, the delegate references both the instance and the method. Ein Delegat kennt nicht den Instanzentyp, abgesehen von der umschlossenen Methode, sodass ein Delegat auf jede Art von Objekt verweisen kann, sofern es eine Methode für das Objekt gibt, die mit der Signatur des Delegaten übereinstimmt.A delegate has no knowledge of the instance type aside from the method it wraps, so a delegate can refer to any type of object as long as there is a method on that object that matches the delegate signature. Wenn ein Delegat erstellt wurde, um eine statische Methode zu umschließen, verweist er nur auf die Methode.When a delegate is constructed to wrap a static method, it only references the method. Betrachten Sie hierzu die folgenden Deklarationen:Consider the following declarations:

public class MethodClass
{
    public void Method1(string message) { }
    public void Method2(string message) { }
}

Zusammen mit der zuvor dargestellten statischen DelegateMethod verfügen Sie jetzt über drei Methoden, die von einer Del-Instanz umschlossen werden können.Along with the static DelegateMethod shown previously, we now have three methods that can be wrapped by a Del instance.

Ein Delegat kann bei Aufruf mehr als eine Methode aufrufen.A delegate can call more than one method when invoked. Dies wird als Multicasting bezeichnet.This is referred to as multicasting. Um der Liste an Methoden des Delegaten, sprich der Aufrufliste, eine weitere Methode hinzuzufügen, müssen lediglich zwei Delegaten mithilfe der Additions- oder Additionszuweisungsoperatoren ('+' oder '+=') hinzugefügt werden.To add an extra method to the delegate's list of methods—the invocation list—simply requires adding two delegates using the addition or addition assignment operators ('+' or '+='). Beispiel:For example:

MethodClass obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod;

//Both types of assignment are valid.
Del allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;

Zu diesem Zeitpunkt enthält allMethodsDelegate drei Methoden in der Aufrufliste: Method1, Method2 und DelegateMethod.At this point allMethodsDelegate contains three methods in its invocation list—Method1, Method2, and DelegateMethod. Die ursprünglichen drei Delegaten, d1, d2 und d3, bleiben unverändert.The original three delegates, d1, d2, and d3, remain unchanged. Wenn allMethodsDelegate aufgerufen wird, werden alle drei Methoden nacheinander aufgerufen.When allMethodsDelegate is invoked, all three methods are called in order. Wenn der Delegat Verweisparameter verwendet, wird der Verweis wiederum nacheinander an jede der drei Methoden übergeben, und alle Änderungen einer Methode sind für die nächste Methode sichtbar.If the delegate uses reference parameters, the reference is passed sequentially to each of the three methods in turn, and any changes by one method are visible to the next method. Wenn eine der Methoden eine Ausnahme auslöst, die nicht innerhalb der Methode abgefangen wird, wird diese Ausnahme an den Aufrufer des Delegaten übergeben und keine der nachfolgenden Methoden in der Aufrufliste wird aufgerufen.When any of the methods throws an exception that is not caught within the method, that exception is passed to the caller of the delegate and no subsequent methods in the invocation list are called. Wenn der Delegat über einen Rückgabewert und/oder out-Parameter verfügt, gibt er den Rückgabewert und die Parameter der letzten aufgerufenen Methode zurück.If the delegate has a return value and/or out parameters, it returns the return value and parameters of the last method invoked. Entfernen Sie eine Methode aus der Aufrufliste, indem Sie den Subtraktions- oder Subtraktionszuweisungsoperator ('-' oder '-=') verwenden.To remove a method from the invocation list, use the decrement or decrement assignment operator ('-' or '-='). Beispiel:For example:

//remove Method1
allMethodsDelegate -= d1;

// copy AllMethodsDelegate while removing d2
Del oneMethodDelegate = allMethodsDelegate - d2;

Da Delegattypen von System.Delegate abgeleitet werden, können die Methoden und Eigenschaften, die durch diese Klasse definiert werden, für den Delegaten aufgerufen werden.Because delegate types are derived from System.Delegate, the methods and properties defined by that class can be called on the delegate. Beispiel: Schreiben Sie Folgendes, um die Anzahl der Methoden in der Aufrufliste eines Delegaten zu ermitteln:For example, to find the number of methods in a delegate's invocation list, you may write:

int invocationCount = d1.GetInvocationList().GetLength(0);

Delegaten mit mehr als einer Methode in der Aufrufliste werden von MulticastDelegate, einer Unterklasse von System.Delegate, abgeleitet.Delegates with more than one method in their invocation list derive from MulticastDelegate, which is a subclass of System.Delegate. Der obige Code funktioniert in jedem Fall, da beide Klassen GetInvocationList unterstützen.The above code works in either case because both classes support GetInvocationList.

Multicastdelegaten werden ausgiebig bei der Ereignisbehandlung verwendet.Multicast delegates are used extensively in event handling. Ereignisquellobjekte senden Ereignisbenachrichtigungen an Empfängerobjekte, die für den Erhalt dieses Ereignisses registriert wurden.Event source objects send event notifications to recipient objects that have registered to receive that event. Um sich für ein Ereignis zu registrieren, erstellt der Empfänger eine Methode zur Behandlung des Ereignisses, dann erstellt er einen Delegaten für die Methode und übergibt den Delegaten an die Ereignisquelle.To register for an event, the recipient creates a method designed to handle the event, then creates a delegate for that method and passes the delegate to the event source. Die Quelle ruft den Delegaten auf, wenn das Ereignis eintritt.The source calls the delegate when the event occurs. Der Delegat ruft dann die Ereignisbehandlungsmethode für den Empfänger auf und übermittelt die Ereignisdaten.The delegate then calls the event handling method on the recipient, delivering the event data. Der Delegattyp für ein bestimmtes Ereignis wird von der Ereignisquelle definiert.The delegate type for a given event is defined by the event source. Weitere Informationen finden Sie unter Ereignisse.For more, see Events.

Beim Vergleichen von zwei unterschiedlichen zugewiesenen Typen zur Kompilierzeit kommt es zu einem Kompilierungsfehler.Comparing delegates of two different types assigned at compile-time will result in a compilation error. Falls die Delegatinstanzen statisch vom Typ System.Delegate sind, dann ist der Vergleich zulässig, gibt jedoch zur Laufzeit "False" zurück.If the delegate instances are statically of the type System.Delegate, then the comparison is allowed, but will return false at run time. Zum Beispiel:For example:

delegate void Delegate1();
delegate void Delegate2();

static void method(Delegate1 d, Delegate2 e, System.Delegate f)
{
    // Compile-time error.
    //Console.WriteLine(d == e);

    // OK at compile-time. False if the run-time type of f 
    // is not the same as that of d.
    System.Console.WriteLine(d == f);
}

Siehe auchSee Also

C#-ProgrammierhandbuchC# Programming Guide
DelegatenDelegates
Verwenden von Varianz bei DelegatenUsing Variance in Delegates
Varianz bei DelegatenVariance in Delegates
Verwenden von Varianz für die generischen Delegaten Func und ActionUsing Variance for Func and Action Generic Delegates
EreignisseEvents