public delegate void Del<T>(T item);
这样一句话包含了一些东西,首先这是一个委托定义
Del<T>(),Del<T>(T item)等等。这样一个委托到底是干嘛的呢?<T>表示一个泛型,例如 List<int> s = new List<int>();T在这是一个类型占位符。
下面看看MSDN对泛型的定义:
泛型是具有占位符(类型参数)的类,结构,接口和方法,这些占位符是类,结构和方法所存储或使用的一个或多个类型的占位符。泛型集合类可以将类型参数用作它所存储的对象的类型的占位符,类型参数作为其字段的类型和气方法的参数类型出现。
T就是你所需要指定的集合的数据或对象类型。T可以是自己定义的类的类型。
public class tclass
{
...
}
List<tclass> s = new List<tclass>();
//////////////////////////////////////////////////
public delegate void Del<T>(T item); //定义泛型委托时并不知道T究竟是什么类型什么东西,也许是类型,也许是接口。一般定义一个类型(delegate实际上是一个类),是需要知道参数的类性的,使用泛型就延迟了参数类型的定义。参数类型只有在实例化时才会知道。
Del<int> i = new Del<int>(notify);
Del<double> d = new Del<double>(fun);
public static void notify(int i)
{MessageBox.Show(i.ToString()); }
public static void fun(double j)
{MessageBox.Show(j.ToString()); }
这几句的意思看看呢,第一句定义一个泛型委托,第二句实例化。此时T是int类型。第三句也是实例化,此时T是double。那么,这样做有什么好处呢?什么情况下需要这样做?继续看
i(5); //委托的执行与被委托方法的执行行为是一致的。
i.invoke(5);
i.BeginInvoke(5,null,null); //后2个参数也是很重要的。要好好掌握
public static void notify(int i,double j) //这样会报错,因为前面泛型委托只要一个参数类型,且只能有一个。
要想有2个参数类型可以这样定义泛型委托
public delegate void Del2<T1,T2>(T1 item1,T2 item2);
Del2<int, double> d2 = new Del2<int, double>(fun2);
public static void fun2(int i, double j) { } //委托相关的方法的参数类型和顺序都不可以颠倒
public delegate void Del3<int>(); //错误 类型形参声明必须是标识符,不能是类型
public delegate void Del3<[]>(); //错误 类型形参声明必须是标识符,不能是类型,也就是说T只能是一个标识符,不能是具体的类型,否则就谈不上泛型了.
public delegate void Del3<T3>(T3[] items); //正确,如下调用,这个定义要求方法参数是一个T3类型的数组
Del3<int> d3 = new Del3<int>(fun3); //等效下句
Del3<int> d31 = fun3; //等效上句 表示 泛型委托Del3<int>的实例方法是fun3。
public static void fun3(int[] i) { }
//典型设计模式定义事件
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;
}