直接看例子吧:
using System;
using System.Windows.Forms;
using System.Threading;
namespace Com.LoonStudio.Example {
public class Car {
// 定义一个汽车事件的委托
public delegate void CarEventHandler(string msg);
// 定义加速事件
public event CarEventHandler OnAccelerate;
// 定义爆炸事件
public event CarEventHandler OnExpose;
public int Speed { set; get; } // 速度
public bool Broken { set; get; } // 是否损坏
public Car() {
Speed = 20;
Broken = false;
}
public void Run() {
while(!Broken) {
Speed += 20;
if (Speed > 120) {
Broken = true;
if (OnExpose != null) { // 引发爆炸事件
OnExpose("坏瓜了, 搞毛线了...");
}
}
else {
if (OnAccelerate != null) { // 引发加速事件
OnAccelerate(string.Format("正在加速, 目前时速{0}km/h", Speed));
}
}
}
}
}
class Program {
static void Main(string[] args) {
Car car = new Car();
car.OnAccelerate += msg => { Console.WriteLine(msg); }; // Lambda表达式
car.OnExpose += new Car.CarEventHandler(Program.Foo); // 事件委托
car.OnAccelerate += delegate(string msg) { Thread.Sleep(1000); }; // 匿名方法
car.Run();
}
private static void Foo(string msg) {
MessageBox.Show(msg, "呕耶", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
上面的例子演示了如何使用委托来做自定义事件,如何使用匿名方法来实现委托代理以及如何使用Lambda表达式。
其实,所谓的委托(delegate)在C语言中叫指向函数的指针,C++中叫仿函数(functor,有些翻译为函数对象),在Java中通过单方法接口回调(callback)来实现。说白了,就是把一个函数通过参数传到另一个函数里面。
另外,还要专门解释一下什么叫回调。普通的函数调用通常是高层代码(应用程序)去调用底层函数(如系统函数、库函数等)。回调则是底层函数执行时调用高层的代码,所以这个术语由此而得名。例如窗体应用中的事件机制,你为按钮、文本框绑定的事件处理代码是谁来调用的,这些都是操作系统收到事件消息后去调用你之前为事件绑定的代码。正常的调用都是我们去掉系统底层的东西,比如你调用Windows API获取当前系统中的前置窗口。这样说应该大概能说清楚什么叫回调了吧:)