您的位置:首页 > 编程语言 > C#

C# 委托(delegate)事件(event)分析

2017-09-08 18:06 585 查看
一.事件的由来

1)

委托也是一种类型,根据面相对象的特性,通常会把一个类型的变量封装到类的内部,并把其设置成private的,然后通过属性来访问该变量,所以在实际编程时委托类型也会定义在类里面。

2)

使用event 关键字来修饰委托变量,其实质上是委托变量的属性。

using System;
namespace LearningSummary
{
//声明一个带参数的委托Greeting(string name)
public delegate void Greeting(string name);
class MainClass
{
public static void Main(string[] args)
{
GreetingManager greetingmanager = new GreetingManager();//初始化委托
greetingmanager.MakeGreet += EnglishGreet; //事件开始付值时不需要初始化
greetingmanager.MakeGreet += ChineseGreet;
greetingmanager.GreetPeople("涵"); //调用上面两个方法;
}
public class GreetingManager
{
public event Greeting MakeGreet; //定义一个委托事件
public void GreetPeople(string name) //这是之后要调用的方法
{
if (MakeGreet != null) //一定要判断事件是否为空,不然当事件为空会报错
{
MakeGreet(name); //这个和委托的调用一样的
}
}
}
public static void EnglishGreet(string name) //这是一个英文问候语的静态方法
{
Console.WriteLine("good morning!~" + name);
}
public static void ChineseGreet(string name) //这是一个中文问候语的静态方法
{
Console.WriteLine("早上好!~" + name);
}
}
}

二.事件的本质

 1)

在类的类部,不管声明它是public 还是protected, 它总是private 的。即在类的外部,不能够用 “=”直接给属性赋值,需用注册 “+=”和注销 “-=”的访问限定符与声明事件时使用的访问限定符相同。(上面红色标明)

 2)

发送(或引发)事件的类称为“发行者”,接受(或处理)事件的类称为“订阅者”。事件的触发必须在发行者内部,在外部不能触发的。

三.观察者模式

由事件的特性引发出了一种设计模式-观察者设计模式,该设计模式是为了定义对象间的一中一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖它的对象会被自动告知并更新,该设计模式包含以下两个类:

=>被监视对象:它往往包含其他对象所感兴趣的内容;

=>监视者:用来监视被监视对象,当被监视对象触发事件时,监视者能自动接收事件。

观察者设计模式 实例一

以热水器烧水为例,当温度达到95度以上时,液晶显示器来显示当前的温度,报警器会报警:

=>被监视对象:热水器的温度,当烧水的温度达到95度时,会触发事件,发送给液晶显示器和报警器;

=>监视者:液晶显示器和报警器,自动接收事件;

创建三个类 Calorfier(热水器)、Monitor(显示器)、Siren(报警器),根据上面的分析编写程序

using System;
namespace EventTest
{
//热水器
public class Calorfier
{
public delegate void WarningDelegate(); // 声明一委托
public event WarningDelegate warningEvent; //定义一委托事件
public int temp; //温度值,在C#中int 类型的初始值是0
public void Heater()
{
while (temp < 95) //判断温度是否小于95度
{
temp++;
if (temp >= 90) //如果温度大于等于95度时
{
Console.WriteLine("当前温度:" + temp);
}
}
if (warningEvent != null) //判断事件是否为空
{
warningEvent(); //事件只能在被观察者的内部执行
}
}
public Calorfier()
{
}
}
}
using System;
namespace EventTest
{
//显示器
public class Monitor
{
public void Display() //显示温度
{
Console.WriteLine("显示当前温度已大于95度");
}
public Monitor()
{
}
}
}
using System;
namespace EventTest
{
//报警器
public class Siren
{
public void GiveAlarm() //报警器发出报警
{
Console.WriteLine("报警器:发出警报");
}
public Siren()
{
}
}
}
class MainClass
{
public static void Main(string[] args)
{
Calorfier calorfier = new Calorfier(); //实例化一个热水器对象
Monitor monitor = new Monitor(); //实例化一个显示器对象
Siren siren = new Siren(); //实例化一个热报警器对象
calorfier.warningEvent += monitor.Display; //赋值
calorfier.warningEvent += siren.GiveAlarm;
calorfier.Heater(); //调用
}
}

观察者设计模式  实例二

使用观察者模式来模拟通讯运营商发消息给手机用户

=>被观察者:运营商 (运营商主动发消息给手机用户)

=>观察者: 手机用户 (接收运营商发来的信息)

建立两个类:

TelePhone(手机用户) Telecom(运营商)
using System;
namespace EventTest
{
//运营商
public class Telecom
{
//声明一个带参数的委托 MsgDelegate(string msg)
public delegate void MsgDelegate(string msg);
public event MsgDelegate msgEvent;

public void SendMsg(string str)
{
msgEvent(str);
}
//通过用单例来得到一个对象
private Telecom() { }

private static Telecom instance;
public static Telecom Instance
{
get{
if (instance == null)
instance = new Telecom();
return instance;
}
}
}
}
using System;
namespace EventTest
{
//手机用户
public class TelePhone
{
public void ReciveMsg(string msg)
{
Console.WriteLine("收到10000号:"+msg);
}
public TelePhone()
{
}
}
}
Main方法中  TelePhone telephone_1 = new TelePhone();
TelePhone telephone_2 = new TelePhone();
TelePhone telephone_3 = new TelePhone();

Telecom.Instance.msgEvent += telephone_1.ReciveMsg;

Telecom.Instance.msgEvent += telephone_2.ReciveMsg;

Telecom.Instance.msgEvent += telephone_3.ReciveMsg;

Telecom.Instance.SendMsg("您已欠费20");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: