关于C#的事件问题希望大神能给讲讲

程序员等于程序猿 2013-12-28 04:47:53

using System;
namespace Wrox.ProCSharp.Delegates
{
public class CarInfoEventArgs:EventArgs
{
public CarInfoEventArgs(string car)

this.car=car;

public string Car{get;private set;}
}
public class CarDealer
{
public event EventHandler<CarInfoEventArgs> NewCarInfo;

public void NewCar(string car)
{
Console.WriteLine("CarDealer,new Car{0}",car);
if(NewCarInfo!=null)
{
NewCarInfo(this,new CarInfoEventArgs(car));
}
}
}
}

请个大神给讲讲,书上的例子,可是还是看不懂这段代码。刚看明白委托,但是被事件给搞晕了;为什么说事件是特殊的委托呢?event EventHandler<CarInfoEventArgs>这个大概是声明事件吧?EventArgs又是什么类?为什么要继承它?请大哥能不能给我详细讲讲这段代码。。也不是很长。但是我有点蒙
...全文
128 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
capricciosoft 2013-12-28
  • 打赏
  • 举报
回复
现在,我们把上面的例子变成事件。 首先,Action<String> 这种“类型”的委托用 可以表示所有 有一个String参数,并没有返回值的函数 的委托。 这也许容易造成混淆。 也许我们想给Action<String>换一个好记的名字呢,并给描述的参数命个名(而不是Action<String> Invoke时IDE提示的什么String Object),再配上好用的针对这种委托类型的注释呢?比如就叫做EventHandler! 当然,我不能实现一个叫做EventHandler的委托描述,因为系统已经有一个了。 为了演示,我们假设名字是EventHandlerB吧! 用下面的代码: /// <summary> /// 演示的“事件”处理过程 /// </summary> /// <param name="car">轿车的名字</param> public delegate void EventHandlerB(String car); public EventHandlerB NewCarInfo; delegate 这样定义一个委托类型: delegate 返回值类型 委托类型名(参数类型 参数名…); 嗯。到这也许你明白了吧。EventHandler不过是系统预定义的用来描述事件处理函数的委托。(它带有一个固定的格式,还有个性化的说明和参数描述) C#和Visual Basic.net均来自Visual Basic 6。 在Visual Basic 6时代,事件处理过程五花八门,用到什么参数,就都列出来。 前面我定义的 void cd_NewCarInfo(String Car) { MessageBox.Show(Car); } 就是这种。需要个Car,就加个Car参数。 在C#和VB.net中所有事件处理函数都统一了形式,比如: private void button1_Click(object sender, EventArgs e) { } 用前面的object 参数传递引发这个事件的对象,e描述你要传入的数据。 如果要让IDE认识,那么e必须是基于EventArgs 类的。 EventArgs 类其实也没提供什么东西。你需要在e中创建的字段,还都需要自己定义。 我们需要一个支持String参数的基于EventArgs 类的类,作为e的类型。 你提供的代码中,下面的这一段就是做这个用的。 public class CarInfoEventArgs:EventArgs { public CarInfoEventArgs(string car) { this.car=car; } public string Car{get;private set;} } 现在你的类变成了 /// <summary> /// 演示的“事件”处理过程 /// </summary> public delegate void EventHandlerB(Object sender, CarInfoEventArgs e); public class CarDealer { public EventHandlerB NewCarInfo; public void NewCar(string car) { if (NewCarInfo != null) { CarInfoEventArgs e=new CarInfoEventArgs(car); NewCarInfo.Invoke(this,e); } } } 测试用例变成了: private void Form1_Load(object sender, EventArgs e) { //cd.NewCarInfo += cd_NewCarInfo; cd.NewCarInfo += (new EventHandlerB(cd_NewCarInfo)); } void cd_NewCarInfo(object sender, CarInfoEventArgs e) { MessageBox.Show(e.Car); } 和真正的事件就差一步了。 首先 public delegate void EventHandlerB(Object sender, CarInfoEventArgs e); 这种类型的委托,系统预定义了一些专门用来表达事件的。 它们这么定义: //public EventHandlerB NewCarInfo; public EventHandler<CarInfoEventArgs> NewCarInfo; 语法是 EventHandler<事件处理过程第二个参数e的类型> (第一个参数是 Object已经确定了) 测试用例那边变成: private void Form1_Load(object sender, EventArgs e) { //cd.NewCarInfo += cd_NewCarInfo; //cd.NewCarInfo += new EventHandlerB(cd_NewCarInfo); cd.NewCarInfo += new EventHandler<CarInfoEventArgs>(cd_NewCarInfo); } 嗯,还差一点,为了让IDE认识它是事件,而不是一个普通的委托,你需要为 NewCarInfo 的定义加上event关键词。 正如你写的代码: public event EventHandler<CarInfoEventArgs> NewCarInfo; 至此,你的代码就这样形成了。 不过,有点遗憾。你不觉得 cd.NewCarInfo += new EventHandler<CarInfoEventArgs>(cd_NewCarInfo); 比较奇怪么? 用public delegate void CarInfoEventHandler(Object sender, CarInfoEventArgs e); 更好看一些吧 完整代码变为 事件和类定义部分: public class CarInfoEventArgs : EventArgs { public CarInfoEventArgs(string car) { this.Car = car; } public string Car { get; private set; } } /// <summary> ///演示的“事件”处理过程 /// </summary> public delegate void CarInfoEventHandler(Object sender, CarInfoEventArgs e); public class CarDealer { public event CarInfoEventHandler NewCarInfo; public void NewCar(string car) { if (NewCarInfo != null) { CarInfoEventArgs e=new CarInfoEventArgs(car); NewCarInfo.Invoke(this,e); } } 测试用例部分: CarDealer cd = new CarDealer(); private void Form1_Load(object sender, EventArgs e) { cd.NewCarInfo+=new CarInfoEventHandler(cd_NewCarInfo); } void cd_NewCarInfo(object sender, CarInfoEventArgs e) { MessageBox.Show(e.Car); } private void button1_Click(object sender, EventArgs e) { cd.NewCar("123"); }
capricciosoft 2013-12-28
  • 打赏
  • 举报
回复
我们从头开始说。 现在,我们抛掉什么事件的概念。 回到需求。 如果要创建一个CarDealer类,提供一个NewCar方法传入字符串,并再用户调用该方法时,调用用户指定的函数并将处理结果传送给它(这个例子是极端,根本就是原样传送),怎么办? 你需要一个变量,去描述和绑定用户指定的函数。 一些语言使用指针去描述这个用户指定的函数。 一些语言使用函数类型变量去描述函数(Function类型,如ActionScript) C#使用委托类型的变量去描述。 我们需要定义一个这样的委托变量: 它描述的函数没有返回值 它描述的函数有一个String类型的参数。 定义的方式是这样的: Action<String> NewCarInfo; Action专门用于定义描述没有返回值的函数的委托。<>中的部分,则是函数的参数的类型。 (定义描述带有返回值的函数,用Func): 要执行这个委托,可以 NewCarInfo.Invoke(car); 或者 NewCarInfo(car);(后面的这个更加直观一些吧) 于是,我们写了这样一个类去满足需求: public class CarDealer { public Action<String> NewCarInfo; public void NewCar(string car) { if (NewCarInfo != null) { //NewCarInfo.Invoke(car); NewCarInfo(car); } } } 这个类有一个方法NewCar,用户调用该方法后,CarDealer类将判断用户是否为委托NewCarInfo绑定了处理函数。如果有,执行它,并传递参数。 下面看测试用例: CarDealer cd = new CarDealer(); private void Form1_Load(object sender, EventArgs e) { cd.NewCarInfo = cd_NewCarInfo; //cd.NewCarInfo = new Action<String>(cd_NewCarInfo); //cd.NewCarInfo += new Action<String>(cd_NewCarInfo); } void cd_NewCarInfo(String Car) { MessageBox.Show(Car); } private void button1_Click(object sender, EventArgs e) { cd.NewCar("123"); } cd_NewCarInfo就是将要传递给Action<String>类型委托NewCarInfo的函数。 显然NewCarInfo委托可以描述cd_NewCarInfo——一个没有返回值带有字符串参数的函数。 最简单的cd.NewCarInfo = cd_NewCarInfo;就进行了绑定,当然,这看上去直观,但并不“正式”。 正式的写法是cd.NewCarInfo = new Action<String>(cd_NewCarInfo); 如果我希望这个通知传递给多个函数呢?或者说一个委托可否绑定多个函数? 当然可以: cd.NewCarInfo += new Action<String>(cd_NewCarInfo); 用这种方式追加。 然后,你回去看看你原始的代码,也许就明白事件为什么就是一种特殊的委托了。 事实上,如果不需要IDE在属性表的事件中列出NewCarInfo,你根本也用不上事件。委托就足够了。
capricciosoft 2013-12-28
  • 打赏
  • 举报
回复
先从“外围”解释一段这段代码。 为此,我基于上面的代码,写了一个测试用例。 CarDealer cd = new CarDealer(); private void Form1_Load(object sender, EventArgs e) { cd.NewCarInfo += new EventHandler<CarInfoEventArgs>(cd_NewCarInfo); } void cd_NewCarInfo(object sender, CarInfoEventArgs e) { MessageBox.Show(e.Car); } private void button1_Click(object sender, EventArgs e) { cd.NewCar("123"); } 你可以看出。你的那段代码的具体功能是: 构建一个CarDealer类共用户使用。 该类提供了一个NewCarInfo事件和一个NewCar方法。 调用NewCar方法将触发NewCarInfo事件,并将NewCar方法的参数输出到事件处理过程的e.Car字段。
  • 打赏
  • 举报
回复
引用 楼主 u012729930 的回复:

using System;
namespace Wrox.ProCSharp.Delegates
{
   public class CarInfoEventArgs:EventArgs
  {
     public CarInfoEventArgs(string car)
    {
       this.car=car;
     }
     public string Car{get;private set;}
  }
   public class CarDealer
  {
    public event EventHandler<CarInfoEventArgs> NewCarInfo;

    public void NewCar(string car)
    {
       Console.WriteLine("CarDealer,new Car{0}",car);
       if(NewCarInfo!=null)
       {
          NewCarInfo(this,new CarInfoEventArgs(car));
       }
    }
  }
}
请个大神给讲讲,书上的例子,可是还是看不懂这段代码。刚看明白委托,但是被事件给搞晕了;为什么说事件是特殊的委托呢?event EventHandler<CarInfoEventArgs>这个大概是声明事件吧?EventArgs又是什么类?为什么要继承它?请大哥能不能给我详细讲讲这段代码。。也不是很长。但是我有点蒙
注释:本代码出自《C#高级编程(第七版)》委托和事件

110,526

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧