c#委托与事件2
首先是一个关机器的一般方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 FoldingMachine folder = new FoldingMachine(); 13 WeldingMachine welder = new WeldingMachine(); 14 PaintingMachine painter = new PaintingMachine(); 15 16 Controller controller = new Controller(); 17 controller.Folder = folder; 18 controller.Welder = welder; 19 controller.Painter = painter; 20 controller.ShutDown(); 21 Console.ReadKey(); 22 } 23 } 24 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class Controller 9 { 10 private FoldingMachine folder; 11 private WeldingMachine welder; 12 private PaintingMachine painter; 13 public void ShutDown() 14 { 15 folder.FinishFolding(); 16 welder.FinishWelding(); 17 painter.PaintOff(); 18 } 19 public FoldingMachine Folder 20 { 21 set { this.folder = value; } 22 } 23 24 public WeldingMachine Welder 25 { 26 set { this.welder = value; } 27 } 28 29 public PaintingMachine Painter 30 { 31 set { this.painter = value; } 32 } 33 34 } 35 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class FoldingMachine 9 { 10 public void StopFolding(int ShutDownTime) 11 { 12 Console.WriteLine("stop FoldingMachine"); 13 } 14 15 public void FinishFolding() 16 { 17 StopFolding(0); 18 } 19 } 20 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class PaintingMachine 9 { 10 public void PaintOff() 11 { 12 Console.WriteLine("stop PaintingMachine"); 13 } 14 } 15 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class WeldingMachine 9 { 10 public void FinishWelding() 11 { 12 Console.WriteLine("stop WeldingMachine."); 13 } 14 } 15 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 FoldingMachine folder = new FoldingMachine(); 13 WeldingMachine welder = new WeldingMachine(); 14 PaintingMachine painter = new PaintingMachine(); 15 16 Controller controller = new Controller(); 17 controller.Folder = folder; 18 controller.Welder = welder; 19 controller.Painter = painter; 20 controller.ShutDown(); 21 controller.StopManchinery(); 22 Console.ReadKey(); 23 } 24 } 25 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class Controller 9 { 10 private FoldingMachine folder; 11 private WeldingMachine welder; 12 private PaintingMachine painter; 13 public delegate void stopManchineryDelegate(); 14 stopManchineryDelegate stopManchinery; 15 16 public Controller() 17 18 { 19 20 // 21 } 22 public stopManchineryDelegate StopManchinery 23 { 24 get { return stopManchinery; } 25 set { stopManchinery += value; } 26 } 27 public void SetStopManchinery() 28 { 29 //stopManchinery = new stopManchineryDelegate(folder.StopFolding); 30 stopManchinery += folder.StopFolding; 31 stopManchinery += welder.FinishWelding; 32 stopManchinery += painter.PaintOff; 33 34 } 35 public void ShutDown() 36 { 37 //folder.FinishFolding(); 38 //welder.FinishWelding(); 39 //painter.PaintOff(); 40 SetStopManchinery(); 41 } 42 public FoldingMachine Folder 43 { 44 set { this.folder = value; } 45 } 46 47 public WeldingMachine Welder 48 { 49 set { this.welder = value; } 50 } 51 52 public PaintingMachine Painter 53 { 54 set { this.painter = value; } 55 } 56 57 } 58 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class FoldingMachine 9 { 10 public void StopFolding() 11 { 12 Console.WriteLine("stop FoldingMachine"); 13 } 14 15 public void FinishFolding() 16 { 17 StopFolding(); 18 } 19 } 20 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class PaintingMachine 9 { 10 public void PaintOff() 11 { 12 Console.WriteLine("stop PaintingMachine"); 13 } 14 } 15 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DelegateDemo 7 { 8 class WeldingMachine 9 { 10 public void FinishWelding() 11 { 12 Console.WriteLine("stop WeldingMachine."); 13 } 14 } 15 }
注意委托(其实就是指针,指向函数的指针,也就是函数指针)的参数要与所指向的函数的参数相同,体现到代码中就是FoldingMachine.cs中的修改。另外一个类中的字段即使是public也不能在另一个类中直接使用,所以代码中使用了方法(controller.StopManchinery();)来使用另一个类中的委托。
lamada表达式:
事件:
事件的调用只能在定义事件的类的内部调用,无论是用public还是private修饰事件。委托违反了封装的原则,事件封装委托,保证了封装。
参考:http://blog.csdn.net/jamestaosh/article/details/4372172
要创建一个事件驱动的程序需要下面的步骤:
1. 声明关于事件的委托;
2. 声明事件;
3. 编写触发事件的函数;
4. 创建事件处理程序;
5. 注册事件处理程序;
6. 在适当的条件下触发事件。
现在我们来编写一个自定义事件的程序。主人养了一条忠实的看门狗,晚上主人睡觉的时候,狗负责看守房子。一旦有小偷进来,狗就发出一个Alarm事件,主人接到Alarm事件后就会采取相应的行动。假设小偷于2009年元旦午夜时分到达。
//事件发送者
class Dog { //1.声明关于事件的委托; public delegate void AlarmEventHandler(object sender, EventArgs e); //2.声明事件; public event AlarmEventHandler Alarm; //3.编写引发事件的函数; public void OnAlarm() { if (this.Alarm != null) { Console.WriteLine("/n狗报警: 有小偷进来了,汪汪~~~~~~~"); this.Alarm(this, new EventArgs()); //发出警报 } } } //事件接收者 class Host { //4.编写事件处理程序 void HostHandleAlarm(object sender, EventArgs e) { Console.WriteLine("主 人: 抓住了小偷!"); } //5.注册事件处理程序 public Host(Dog dog) { dog.Alarm += new Dog.AlarmEventHandler(HostHandleAlarm); } } //6.现在来触发事件 class Program { static void Main(string[] args) { Dog dog = new Dog(); Host host = new Host(dog); //当前时间,从2008年12月31日23:59:50开始计时 DateTime now = new DateTime(2008, 12, 31, 23, 59, 50); DateTime midnight = new DateTime(2009, 1, 1, 0, 0, 0); //等待午夜的到来 Console.WriteLine("时间一秒一秒地流逝... "); while (now < midnight) { Console.WriteLine("当前时间: " + now); System.Threading.Thread.Sleep(1000); //程序暂停一秒 now = now.AddSeconds(1); //时间增加一秒 } //午夜零点小偷到达,看门狗引发Alarm事件 Console.WriteLine("/n月黑风高的午夜: " + now); Console.WriteLine("小偷悄悄地摸进了主人的屋内... "); dog.OnAlarm(); } }
http://blog.csdn.net/Wiiix/article/details/51463977
下面再看一个例子:
在我们创建一个事件之前,我们需要一个委托,而一般标准的委托声明如下:
public delegate void EventHandler(object sender, System.EventArgs e);
第一个形参object sender定义了对象来源,第二个形参放的是继承自System.EventArgs的类,一般上这个类包含了事件的详细信息。
例子:
class ButtonEventArgs:EventArgs
{
public string time;
}
在这里我们不需要传递什么事件信息,所以我们用基类EventArgs就好。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public delegate void EventHandler(object sender, System.EventArgs e); 2 3 class Publisher 4 { 5 public event EventHandler Added; //定义发生事件 6 7 8 protected virtual void OnAdded(System.EventArgs e) //当事件发生中触发方法 9 { 10 if(Added!=null) 11 { 12 Added(this, e); 13 } 14 } 15 public void Add(object value) //触发事件的方法 16 { 17 18 OnAdded(System.EventArgs.Empty); 19 } 20 } 21 22 23 24 class Subscriber 25 { 26 void AddedEventHandler(object sender,System.EventArgs e) 27 { 28 System.Console.WriteLine("AddEvent occured"); 29 } 30 31 static void Main() 32 { 33 Subscriber s = new Subscriber(); 34 Publisher p = new Publisher(); 35 p.Added += s.AddedEventHandler; 36 p.Add(10); 37 } 38 }
事件的使用步骤如下:
存放事件的类
1.定义事件
2.触发事件的方法(protected)
3.间接触发事件的方法(public)
触发事件的类
1.定义方法
2.注册方法
3.触发方法
http://www.cnblogs.com/yinqixin/p/5067033.html
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 自定义事件一 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 Dog dog = new Dog(); 13 Host host = new Host(dog ); 14 DateTime now = new DateTime(2011, 12, 31, 23, 59, 55); 15 DateTime midnight = new DateTime(2012, 1, 1, 0, 0, 0); 16 while (now < midnight) 17 { 18 Console.WriteLine("当前时间" + now); 19 System.Threading.Thread.Sleep(1000); 20 now = now.AddSeconds(1); 21 } 22 Console.WriteLine("\n月黑风高的午夜:" + now); 23 Console.WriteLine("小偷进了主人的屋内..........."); 24 dog.OnAlarm(); 25 Console.ReadKey(); 26 } 27 } 28 class Dog 29 { 30 //第一:声明关于事件的委托 31 public delegate void AlarmEventHandler(object sender, EventArgs e); 32 //第二:声明事件 33 public event AlarmEventHandler Alarm;//前面的public没用,这个Alarm事件仍然是private的,可以在类外绑定方法,不能运行这个事件 34 //第三:编写引发shijian的函数 35 public void OnAlarm() 36 { 37 if (this.Alarm != null) 38 { 39 Console.WriteLine("\n狗报警,有小偷进来了,汪汪汪~~~"); 40 this.Alarm(this, new EventArgs());//运行这个事件;this 当前对象,this.Alarm是当前对象多引用的事件 41 } 42 } 43 } 44 class Host 45 { 46 //第四:编写事件的处理程序 47 void HostHandeAlarm(object sender, EventArgs e) 48 { 49 Console.WriteLine("主人:抓住了小偷!~"); 50 } 51 //第五:注册事件的处理程序 52 public Host(Dog dog) 53 { 54 dog.Alarm += new Dog.AlarmEventHandler(HostHandeAlarm); 55 } 56 } 57 58 }