学C#的时间也不短了,本来以为自己对委托与事件的理解应该是没问题的。但最近做工程的时候总觉得不甚顺手,思来想去都得不到解决方法。于是重新去认识了一遍委托与事件。
打个比方,现在有一个类叫Human,其中有事件hungryEventHandle,那么当把一个human的对象放在一间面馆里头并且触发了hungryEventHandle的事件之后,面馆就会给human提供一碗面,当这个human不在面馆而是在一间饭店的话,饭店提供的就是饭了。human还是那个human,但在不同的地方触发相同的事件之后得到的东西却并不相同。这个就是事件的关键所在,它并不执行代码,而只提供一个通知,代码是别的对象执行的。
Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Deletegate
{
/// <summary>
/// 定义委托
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void NumberReachedEventHandler(object sender,
NumberReachedEventArgs e);
/// <summary>
/// 定义NumberReachedEventArgs,从系统的EventArgs继承
/// </summary>
public class NumberReachedEventArgs : EventArgs
{
private int _reached;
//构造函数,num为参数传入_reached
public NumberReachedEventArgs(int num)
{
this._reached = num;
}
//定义属性
public int ReachedNumber
{
get
{
return _reached;
}
}
}
/// <summary>
/// Counter类
/// </summary>
public class Counter
{
//声名事件,它的类型是委托NumberReachedEventHandler,就是说Counter本身有一个NumberReached的事件
public event NumberReachedEventHandler NumberReached;
public Counter()
{
}
public void CountTo(int countTo, int reachableNum)
{
if(countTo < reachableNum)
throw new ArgumentException(
"reachableNum should be less than countTo");
for(int ctr=0;ctr<=countTo;ctr++)
{
if(ctr == reachableNum)
{
//创建事件参数e,并将reachableNum传入
NumberReachedEventArgs e = new NumberReachedEventArgs(reachableNum);
OnNumberReached(e);
return;//don't count any more
}
}
}
protected virtual void OnNumberReached(NumberReachedEventArgs e)
{
if(NumberReached != null)
{
//这里是全部的关键,NumberReached的实体不在Counter里,因为它是一个事件,它只负责通知外面的对象来实现这个事件所要做的事
NumberReached(this, e);//Raise the event
}
}
}
public partial class Form1 : Form
{
Counter oCounter = new Counter();
public Form1()
{
InitializeComponent();
//首先,oCounter本身有NumberReached的事件,这里是在Form1中创建一个事件,然后放在oCounter的事件中,其实就相当于
//把Form1中的函数oCounter_NumberReached放进了oCounter中,那么当oCounter触发了这个事件的时候,oCounter就会知道
//触发这个事件的时候该做什么事。准确来说就是去执行oCounter_NumberReached的代码。
oCounter.NumberReached += new NumberReachedEventHandler(oCounter_NumberReached);
}
private void button1_Click(object sender, EventArgs e)
{
if (txtCountTo.Text == "" || txtReachable.Text == "")
return;
oCounter.CountTo(Convert.ToInt32(txtCountTo.Text), Convert.ToInt32(txtReachable.Text));
}
private void oCounter_NumberReached(object sender, NumberReachedEventArgs e)
{
MessageBox.Show("Reached: " + e.ReachedNumber.ToString());
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Deletegate
{
/// <summary>
/// 定义委托
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void NumberReachedEventHandler(object sender,
NumberReachedEventArgs e);
/// <summary>
/// 定义NumberReachedEventArgs,从系统的EventArgs继承
/// </summary>
public class NumberReachedEventArgs : EventArgs
{
private int _reached;
//构造函数,num为参数传入_reached
public NumberReachedEventArgs(int num)
{
this._reached = num;
}
//定义属性
public int ReachedNumber
{
get
{
return _reached;
}
}
}
/// <summary>
/// Counter类
/// </summary>
public class Counter
{
//声名事件,它的类型是委托NumberReachedEventHandler,就是说Counter本身有一个NumberReached的事件
public event NumberReachedEventHandler NumberReached;
public Counter()
{
}
public void CountTo(int countTo, int reachableNum)
{
if(countTo < reachableNum)
throw new ArgumentException(
"reachableNum should be less than countTo");
for(int ctr=0;ctr<=countTo;ctr++)
{
if(ctr == reachableNum)
{
//创建事件参数e,并将reachableNum传入
NumberReachedEventArgs e = new NumberReachedEventArgs(reachableNum);
OnNumberReached(e);
return;//don't count any more
}
}
}
protected virtual void OnNumberReached(NumberReachedEventArgs e)
{
if(NumberReached != null)
{
//这里是全部的关键,NumberReached的实体不在Counter里,因为它是一个事件,它只负责通知外面的对象来实现这个事件所要做的事
NumberReached(this, e);//Raise the event
}
}
}
public partial class Form1 : Form
{
Counter oCounter = new Counter();
public Form1()
{
InitializeComponent();
//首先,oCounter本身有NumberReached的事件,这里是在Form1中创建一个事件,然后放在oCounter的事件中,其实就相当于
//把Form1中的函数oCounter_NumberReached放进了oCounter中,那么当oCounter触发了这个事件的时候,oCounter就会知道
//触发这个事件的时候该做什么事。准确来说就是去执行oCounter_NumberReached的代码。
oCounter.NumberReached += new NumberReachedEventHandler(oCounter_NumberReached);
}
private void button1_Click(object sender, EventArgs e)
{
if (txtCountTo.Text == "" || txtReachable.Text == "")
return;
oCounter.CountTo(Convert.ToInt32(txtCountTo.Text), Convert.ToInt32(txtReachable.Text));
}
private void oCounter_NumberReached(object sender, NumberReachedEventArgs e)
{
MessageBox.Show("Reached: " + e.ReachedNumber.ToString());
}
}
}