今天主要写点自己最近关于c#委托和事件的理解,写的比较乱,不明白的地方可以一起讨论下。(欢迎大家提出不同的意见和见解)。
一. 委托
1. .net是以委托的形式来实现C/C++函数指针的概念。
区别:C指针是指向存储单元,不能知道参数和返回类型。
.net把委托作为一种类型安全的操作。
2. 委托:把方法传递给其他的方法(类似于传值类型参数)如:
class A{
public void ChineseName(String name){......} //值类型参数的方法
public void EnglishName(String name){........} //值类型参数的方法
public delegate void MakeDelegate(String name); //委托的定义
public void DisplayName(String name,MakeDelegate MakeName) //委托相当于是MakeName方法的类型(如name的类型是String)
{
MakeName(name);
}
static void Main(String[] args)
{
MakeDelegate MD=ChienseName; //给委托变量绑定方法,第一个用=
MD+=EnglishName; //给委托变量绑定方法,第二个用+=
//MD-=EnglishName; //取消绑定
A a=new A();
a.Display("RUby",MD);
}
}
3.委托包含多个方法,称为多播委托。(如上面包含了两个方法,委托的签名就必须返回void,否则就只能得到委托调用的最后一个方法)。
二. 事件
”事件“是指当对象发生某些事情时,向其他对象提供通知的方法。“事件”一般有两个角色:事件的发送方,事件的接受方;事件的发送方
是指触发事件的对象,事件的接受方是想在某种事件发生时被通知的对象。事件的接受器在某个地方有一个方法,它负责处理事件。在每次发生
已事件的注册的时间时就执行这个时间处理程序,此时就使用到了委托。发送器对接收器一无所知,所以及使用委托作为中介来设置两者之间的
引用类型。发送器定义接收器要使用的委托,接收器将事件处理程序注册到事件中。
下面的程序用了委托和事件及Observer设计模式。
热水器(监视对象,有其他对象(如:Alarm监视者)感兴趣的字段temperatrue)
Heater.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace Delegate_format
{
//public void delegate
class Heater
{
private int temperature;
public string type = "Realfire 001";//添加型号作为演示
public string area = "China xin";//添加产地作为演示
public delegate void BoiledEventHandler(object sender,BoilerEventArgs e);
public event BoiledEventHandler Boiled;//声明事件
public class BoilerEventArgs : EventArgs
{
public readonly int temperature;
public BoilerEventArgs(int temperature)
{
this.temperature=temperature;
}
}
//供继承heater的类重写,以便继承类拒绝其他对象对他的监视
protected virtual void OnBoiled(BoilerEventArgs e)
{
if (Boiled != null)//如果有对象注册
{
Boiled(this, e);//调用所有注册对象的方法
}
}
//烧水
public void BoilWater()
{
for (int i = 0; i <= 100; i++)
{
temperature = i;
if (temperature > 95)
{
//建立BoiledEventArgs对象
BoilerEventArgs e = new BoilerEventArgs(temperature);
OnBoiled(e);
}
}
}
}
}
报警器(监视者)
Alram.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace Delegate_format
{
class Alarm
{
public void MakeAlert(object sender, Heater.BoilerEventArgs e)
{
Heater heater = (Heater)sender;
//访问sender的公共字段
Console.WriteLine("Alarm:{0}-{1}:",heater.area,heater.type);
Console.WriteLine("Alerm:嘀嘀嘀,水已经{0}度了",e.temperature);
Console.WriteLine();
}
}
}
显示器(监视者)
Display.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace Delegate_format
{
class Display
{
public static void ShowMsg(object sender,Heater.BoilerEventArgs e) //静态方法
{
Heater heater = (Heater)sender;
Console.WriteLine("Display:{0}-{1}:", heater.area, heater.type);
Console.WriteLine("Display:嘀嘀嘀,水已经{0}度了", e.temperature);
Console.WriteLine();
}
}
}
主程序入口
Program.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace Delegate_format
{
class Program
{
static void Main(string[] args)
{
Heater heater = new Heater();
Alarm alarm = new Alarm();
heater.Boiled += alarm.MakeAlert;
heater.Boiled += Display.ShowMsg;
heater.BoilWater();
Console.Read();
}
}
}