Partager via


Délégués génériques (guide de programmation C#)

Un délégué peut définir ses propres paramètres de type. Le code qui référence le délégué générique peut spécifier l’argument de type pour créer un type construit fermé, comme lors de l’instanciation d’une classe générique ou de l’appel d’une méthode générique, comme illustré dans l’exemple suivant :

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

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

La version 2.0 de C# a une nouvelle fonctionnalité appelée conversion de groupe de méthodes, qui s'applique aussi bien aux types délégués concrets qu'aux types délégués génériques, et vous permet d'écrire la ligne précédente avec cette syntaxe simplifiée :

Del<int> m2 = Notify;

Les délégués définis dans une classe générique peuvent utiliser les paramètres de type de classe générique de la même façon que les méthodes de classe.

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

Le code qui fait référence au délégué doit spécifier l’argument de type de la classe conteneur, comme suit :

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

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

Les délégués génériques sont particulièrement utiles dans la définition d’événements en fonction du modèle de conception classique, car l’argument expéditeur peut être fortement typé et n’a plus besoin d’être converti vers et depuis Object.

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;
}

Voir aussi