PDF版下载:第2章-C#中的委托和事件
这个是完整的第2章,C#中的委托和事件,按照编辑要求,排版比较散,实际没那么多页的,成书时估计也就40页。初稿,还会有较大改动。这是写作前期的最后一篇样章。
我们现在来做一个小程序:创建一个Windows窗体应用程序,然后在默认创建的Form1上添加两个按钮,分别命名为btnClickMe1和btnClickMe2,显示的文本为“点击我1”、“点击我2”,如下图所示:
然后我们希望在点击这两个按钮的时候,能够弹出一个对话框,向用户显示一个提示,例如“您好,我的读者,希望您能喜欢本书!”(顺便一提,我是真心这么希望的^^)。如果在往常,你可能会毫不犹豫的在按钮上双击,然后编写按钮的事件处理代码,但是我们现在在讲委托和事件,所以让我们换一种方式,像下面这样修改Form1.cs文件:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
btnClickMe1.Click += new EventHandler(btnClickMe_Click);
btnClickMe2.Click += new EventHandler(btnClickMe_Click);
}
void btnClickMe_Click(object sender, EventArgs e) {
MessageBox.Show("您好,我的读者,希望您能喜欢本书!");
}
}
我知道这段代码现在已经不会为你造成任何障碍了,所以就不费时间解释它了。但是我们的第一个反应就是代码重用了,因为两个Click事件共享了同一个事件处理方法。接下来我们再思考一下,像这种两个按钮共用同一个Click事件处理方法的情况并不多见,现在让我们删除掉btnClickMe2,仅保留一个btnClickMe1,好了,现在你看出问题了么?btnClickMe_Click()方法仅仅是为btnClickMe1服务,但是它们却离得如此之远,以至于我们在窗体代码很多的情况下(你可以想像一下窗体有几百行代码,而btnClickMe_Click()隐藏在一个小角落里)不得不花些时间来寻找它。我们会想,要是有一种语法,能够直接将方法体付给btnClickMe1的Click事件就好了,比如说像下面这样:
btnClickMe1.Click += {
MessageBox.Show("您好,我的读者,希望您能喜欢本书!");
};
现在你应该知道我要讲什么了,这就是本小节的主题――匿名方法,只不过上面的代码还需要再做一点修改,因为我们还缺少了一样东西,就是方法的签名:
btnClickMe1.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("您好,我的读者,希望您能喜欢本书!");
};
OK,现在运行程序,你可以发现程序已经运转如常了。但是仔细看看这段代码,你是否还能发现问题?好吧,我向你提示一下:方法体既没有使用参数sender,也没有使用参数e,但是为了让编译器通过,我们却把它们添加了进来,这样是不是很冗余?为了解决这个问题,C#又提供了一种更简洁的语法,在你不使用方法参数时使用,就好像我们现在这种情况:
btnClickMe1.Click += delegate{
MessageBox.Show("您好,我的读者,希望您能喜欢本书!");
};
这和我们上面的推断几乎完全一样,只是多了个delegate关键字而已,是不是很方便的能力?下次编写代码时,你就可以试着使用一下它,这样会使你的印象更加牢固。