Delegati generici (Guida per programmatori C#)

Un delegato può definire i propri parametri di tipo. Il codice che fa riferimento al delegato generico può specificare l'argomento di tipo per creare un tipo costruito chiuso, analogamente a quanto avviene quando si crea un'istanza di una classe generica o si chiama un metodo generico, come illustrato nell'esempio riportato di seguito:

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

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

C# versione 2.0 dispone di una nuova funzionalità denominata conversione dei gruppi di metodi, applicabile a tipi di delegati sia concreti che generici, che consente di scrivere la riga precedente con la seguente sintassi semplificata:

Del<int> m2 = Notify;

I delegati definiti in una classe generica possono utilizzare i parametri di tipo di classi generiche analogamente ai metodi di classi.

class Stack<T>
{
    T[] items;
    int index;

    public delegate void StackDelegate(T[] items);
}

Il codice che fa riferimento al delegato deve specificare l'argomento di tipo della classe che lo contiene, come riportato di seguito:

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

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

I delegati generici sono particolarmente utili nella definizione di eventi in base al modello di progettazione tipico perché l'argomento del mittente può essere fortemente tipizzato e non deve più essere sottoposto a cast sull'oggetto Object e da esso.

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

Vedere anche

Riferimenti

Introduzione ai generics (Guida per programmatori C#)

Metodi generici (Guida per programmatori C#)

Classi generiche (Guida per programmatori C#)

Interfacce generiche (Guida per programmatori C#)

Delegati (Guida per programmatori C#)

System.Collections.Generic

Concetti

Guida per programmatori C#

Generics in .NET Framework