谈谈事件(Event)
事件(Event):
事件的定义不太好描述,可以这样说,事件是一个对象对另一个有动作的对象的响应。就像是一个是发生器,一个是接收器,发生的目的,是因为可以被接收。
定义事件时,要带2个参数,一个是引起事件的对象本身,另一个是继承自EventArgs类的对象。
事件存在的基础是委托,基于以下定义的委托:
定义了一个委托,接收的方法不返回任何值,方法的参数有2个,一个是本身对象object,另一个是继承自EventArgs类的对象ChangeEventArgs,定义ChangeEventArgs的目的是可以使事件获取更多的信息,比如建立一个类EventArrayList,继承自ArrayList,在Add()中,我们需要将加入的对象的字符串写入日志中,那么ChangeEventArgs可以用户存储字符串。
比较下面的代码:
原因在于ChangeEventHandler委托的实例OnChange,作为事件来说,OnChange是一个多点委托,使用+=来加入委托事件。
事件的定义不太好描述,可以这样说,事件是一个对象对另一个有动作的对象的响应。就像是一个是发生器,一个是接收器,发生的目的,是因为可以被接收。
定义事件时,要带2个参数,一个是引起事件的对象本身,另一个是继承自EventArgs类的对象。
事件存在的基础是委托,基于以下定义的委托:
public delegate void ChangeHandler(object sender,ChangeEventArgs e);
//其中,ChangeEventArgs是继承自EvnetArgs的对象
public class ChangeEventArgs:EventArgs
{
private string message;
public ChangeEventArgs(string message)
{
this.message=message;
}
public string Message
{
if(this.message==null)
{
throw new Exception("message is null");
}
return message;
}
}
//其中,ChangeEventArgs是继承自EvnetArgs的对象
public class ChangeEventArgs:EventArgs
{
private string message;
public ChangeEventArgs(string message)
{
this.message=message;
}
public string Message
{
if(this.message==null)
{
throw new Exception("message is null");
}
return message;
}
}
定义了一个委托,接收的方法不返回任何值,方法的参数有2个,一个是本身对象object,另一个是继承自EventArgs类的对象ChangeEventArgs,定义ChangeEventArgs的目的是可以使事件获取更多的信息,比如建立一个类EventArrayList,继承自ArrayList,在Add()中,我们需要将加入的对象的字符串写入日志中,那么ChangeEventArgs可以用户存储字符串。
比较下面的代码:
public class EventArrayList1:ArrayList
{
public delegate void ChangeEventHandler(object sender,ChangeEventArgs e);
public ChangeEventHandler OnChange;
public override int Add(object value)
{
//ChangeEventArgs实例接收字符
ChangeEventArgs e=new ChangeEventArgs(value.ToString());
//如果OnChange不为空,即被实例化了,执行委托
if(OnChange!=null )
{
OnChange(this,e);
}
return base.Add(value);
}
}
//在看看下面这段代码
public class EventArrayList2:ArrayList
{
public delegate void ChangeEventHandler(object sender,ChangeEventArgs e);
public event ChangeEventHandler OnChange;
public override int Add(object value)
{
//ChangeEventArgs实例接收字符
ChangeEventArgs e=new ChangeEventArgs(value.ToString());
//如果OnChange不为空,即被实例化了,执行委托
if(OnChange!=null )
{
OnChange(this,e);
}
return base.Add(value);
}
}
{
public delegate void ChangeEventHandler(object sender,ChangeEventArgs e);
public ChangeEventHandler OnChange;
public override int Add(object value)
{
//ChangeEventArgs实例接收字符
ChangeEventArgs e=new ChangeEventArgs(value.ToString());
//如果OnChange不为空,即被实例化了,执行委托
if(OnChange!=null )
{
OnChange(this,e);
}
return base.Add(value);
}
}
//在看看下面这段代码
public class EventArrayList2:ArrayList
{
public delegate void ChangeEventHandler(object sender,ChangeEventArgs e);
public event ChangeEventHandler OnChange;
public override int Add(object value)
{
//ChangeEventArgs实例接收字符
ChangeEventArgs e=new ChangeEventArgs(value.ToString());
//如果OnChange不为空,即被实例化了,执行委托
if(OnChange!=null )
{
OnChange(this,e);
}
return base.Add(value);
}
}
上面2段代码,唯一的差别在于OnChange的声明中有没有event关键字。
建立测试类,
public class Test
{
EventArrayList1 event1=new EventArrayList1();
EventArrayList2 event2=new EventArrayList2();
event1.OnChange+=new event1.ChangeEventHandler(dosomething);
event2.OnChange+=new event2.ChangeEventHandler(dosomething);
//
private void dosomething(object sender,ChangeEventArgs e)
{
}
}
这样当Test类中的event1,event2执行Add()时,就会触发dosomething(),2者没有任何不同,那么为什么存在2个声明方法呢?{
EventArrayList1 event1=new EventArrayList1();
EventArrayList2 event2=new EventArrayList2();
event1.OnChange+=new event1.ChangeEventHandler(dosomething);
event2.OnChange+=new event2.ChangeEventHandler(dosomething);
//
private void dosomething(object sender,ChangeEventArgs e)
{
}
}
原因在于ChangeEventHandler委托的实例OnChange,作为事件来说,OnChange是一个多点委托,使用+=来加入委托事件。
event1.ChangeEventHander+=new event1.ChangeEventHandler(dosomething);
event2.ChangeEventHander+=new event2.ChangeEventHandler(dosomething);
如果没有定义OnChange 为event,那么可能使用操作符=,从而这样定义:event2.ChangeEventHander+=new event2.ChangeEventHandler(dosomething);
event1.ChangeEventHander=new event1.ChangeEventHandler(dosomething);
event2.ChangeEventHander=new event2.ChangeEventHandler(dosomething);
这样会变成单点委托,只执行一次。event2.ChangeEventHander=new event2.ChangeEventHandler(dosomething);