泛型委派 (C# 程式設計手冊)Generic Delegates (C# Programming Guide)

委派可以定義自己的型別參數。A delegate can define its own type parameters. 參考泛型委派的程式碼,可以指定型別引數建立封閉式建構類型,就像在具現化泛型類別或呼叫泛型方法時一樣,如下列範例所示:Code that references the generic delegate can specify the type argument to create a closed constructed type, just like when instantiating a generic class or calling a generic method, as shown in the following example:

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

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

C# 2.0 版具有方法群組轉換新功能,適用於實體及泛型委派類型,並可讓您使用這個簡化的語法撰寫上一行:C# version 2.0 has a new feature called method group conversion, which applies to concrete as well as generic delegate types, and enables you to write the previous line with this simplified syntax:

Del<int> m2 = Notify;

在泛型類別中定義的委派,可以使用和類別方法相同的方式,使用泛型類別類型參數。Delegates defined within a generic class can use the generic class type parameters in the same way that class methods do.

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

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

參考委派的程式碼必須指定包含類別的型別引數,如下所示:Code that references the delegate must specify the type argument of the containing class, as follows:

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

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

泛型委派在根據一般設計模式定義事件方面特別有幫助,因為傳送者引數可以是強型別,不必再在 Object 間來回轉換。Generic delegates are especially useful in defining events based on the typical design pattern because the sender argument can be strongly typed and no longer has to be cast to and from 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)
    {
        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;
}

另請參閱See also