为了让委托做某事,必须满足4个条件:
•声明委托类型;
•必须有一个方法包含了要执行的代码;
•必须创建一个委托实例;
•必须调用(invoke)委托实例。
1. 声明委托类型
delegate void StringProcessor(string input);
2. 为委托实例的操作找到一个恰当的方法
看看以下StringProcessor实例的5个备选方法签名:
void PrintString(string x) //符合要求,所以可以用它创建一个委托实例
void PrintInteger(int x) //虽然也有一个参数,但不是string类型,所以不兼容StringProcessor
void PrintTwoStrings(string x, string y) //第1个参数的类型匹配,但参数数量不匹配,所以也不兼容
int GetStringLength(string x) //有正确的参数列表,但返回类型不是void (如果委托类型有返回类型,方法的返回类型也必须与之匹配。)
void PrintObject(object x) //符合要求,这是由于string是从object派生的。把这个方法作为StringProces-sor的一个实例来使用是合情合理的,但C# 1要求委托必须具有完全相同的参数类型。C# 2改善了这个状况
3. 创建委托实例
指定在调用委托实例时就执行该方法 ,将该方法称为委托实例的操作
StringProcessor proc1, //定义
proc2;proc1 = new StringProcessor(StaticMethods.PrintString);//实例化(传入类的静态方法)
InstanceMethods instance = new InstanceMethods(); //这个对象称为操作的目标。调用委托实例时,就会为这个对象调用方法。如果操作在同一个类中(这种情况经常发生,尤其是在UI代码中写事件处理程序时),那么两种限定方式都不需要——实例方法隐式将this引用作为前缀。同样,这些规则和你直接调用方法时没什么两样
proc2 = new StringProcessor(instance.PrintString);//实例化(传入类的实例方法)
4. 调用委托实例
void Invoke(string input)
完整的例子
另外一个例子:
// 委托使用的演示
class Program{
// 1. 使用delegate关键字来定义一个委托类型
delegate void MyDelegate(int para1, int para2);
static void Main(string[] args) {
// 2. 声明委托变量d
MyDelegate d;
// 3. 实例化委托类型,传递的方法也可以为静态方法,这里传递的是实例方法
d = new MyDelegate(new Program().Add);
// 4. 委托类型作为参数传递给另一个方法
MyMethod(d);
Console.Read();
}
// 该方法的定义必须与委托定义相同,即返回类型为void, 两个int类型的参数
void Add(int para1, int para2) {
int sum = para1 + para2;
Console.WriteLine("两个数的和为:"+sum);
}
// 方法的参数是委托类型
private static void MyMethod(MyDelegate mydelegate)
{
// 5.在方法中调用委托
mydelegate(1,2);
}
}
说明 最终的垃圾(或者不是,视情况而定) 必须注意,假如委托实例本身不能被回收,委托实例会阻止它的目标被作为垃圾回收。这可能造成明显的内存泄漏(leak),尤其是假如某“短命”对象调用了一个“长命”对象中的事件,并用它自身作为目标。“长命”对象间接容纳了对“短命”对象的一个引用,延长了“短命”对象的寿命。