Freigeben über


Generische Delegaten (C#-Programmierhandbuch)

Ein Delegat kann seine eigenen Typparameter definieren. Code, der auf den generischen Delegaten verweist, kann das Typargument angeben, um einen geschlossenen konstruierten Typ zu erstellen, genau wie beim Instanziieren einer generischen Klasse oder aufrufen einer generischen Methode, wie im folgenden Beispiel gezeigt:

public delegate void Del<T>(T item);
public static void Notify(int i) { }

Del<int> m1 = new Del<int>(Notify);

C# Version 2.0 verfügt über ein neues Feature namens Methodengruppenkonvertierung, das sowohl für konkrete als auch für generische Delegattypen gilt und Ihnen ermöglicht, die vorherige Zeile mit dieser vereinfachten Syntax zu schreiben:

Del<int> m2 = Notify;

Delegaten, die in einer generischen Klasse definiert sind, können die generischen Klassentypparameter auf die gleiche Weise wie Klassenmethoden verwenden.

class Stack<T>
{
    public delegate void StackDelegate(T[] items);
}

Code, der auf den Delegaten verweist, muss das Typargument der enthaltenden Klasse wie folgt angeben:

private static void DoWork(float[] items) { }

public static void TestStack()
{
    Stack<float> s = new Stack<float>();
    Stack<float>.StackDelegate d = DoWork;
}

Generische Delegaten sind besonders nützlich zum Definieren von Ereignissen, die auf dem typischen Entwurfsmuster basieren, denn das Absenderargument kann mit starker Typisierung versehen werden und muss nicht länger in das bzw. aus dem Object umgewandelt werden.

delegate void StackEventHandler<T, U>(T sender, U eventArgs);

class Stack<T>
{
    public class StackEventArgs : System.EventArgs { }
    public event StackEventHandler<Stack<T>, StackEventArgs>? StackEvent;

    protected virtual void OnStackChanged(StackEventArgs a)
    {
        if (StackEvent is not null)
            StackEvent(this, a);
    }
}

class SampleClass
{
    public void HandleStackChange<T>(Stack<T> stack, Stack<T>.StackEventArgs args) { }
}

public static void Test()
{
    Stack<double> s = new Stack<double>();
    SampleClass o = new SampleClass();
    s.StackEvent += o.HandleStackChange;
}

Siehe auch