委托与事件
明天还要上班,可我这会儿,总想着写篇博文,要不感觉就像丢了件东西似的,睡不着。成全我自己吧。
刚走入工作的我,为了更好的工作,我就让自己回炉一次,更深入的理解各个知识点。
今晚就从委托与事件开始。。
1.什么是委托。
委托是一种数据结构,能够引用静态方法或引用实例及其实例方法,他是完全面向对象的,同时也封装了对象实例和方法。委托实例封
装了一个调用列表,该列表包含了一个会多个方法,每个方法称为一个可调用实体。
2.我用代码展示委托使用的全过程。(看从1-->5的顺序)
//1.委托的声明,delegate为声明委托的关键字;
//public为修饰符,还可以有的修饰符为 protected、internal、private、new
//new修饰符,只能在其他类型中声明委托时使用,他表示所标明的委托会隐藏具有相同名称的继承成员
public delegate void D(int i, int j);
public class Program
{
static void Main(string[] args)
{
//3.委托实例化可以创建委托类型的实例,并向该实例注册方法列表
//委托类型的实例方法列表可以为静态方法,实例方法,或者另外一个委托实例。
D d1 = new D(U.F1);
D d2 = new D(U.F2);
D d3 = d1 + d2; //这样表示d3实例依次调用U类的F1、F2方法
D d4 = d3 - d1; //表示从d3实例的方法列表末端查找,如果该方法包括d1,则移除
//5.委托的调用
d1(200, 100); //输出为300
d2(200, 100); //100
d3(50, 10); //60 40 这里由于实例方法列表中有2个方法,也就调用执行了2个方法,故导出2个值
d4(70, 40); // 30
Console.ReadKey();
}
}
public class U
{
//2.创建向委托注册的方法
//如果一个方法能够注册到某一个委托中,那么该方法的签名必须与该委托所指定的签名完全匹配
//匹配规则有2:返回类型必须相同;方法参数必须相同。
public static void F1(int a, int b)
{
Console.WriteLine((a+b).ToString());
}
public static void F2(int w, int j)
{
Console.WriteLine((w-j).ToString());
}
}
3. 委托的你深入应用
public delegate void helloWorld(string name); //声明委托
class Program
{
static void Main(string[] args)
{
//最初的委托
helloWorld ffdelegate = new Program().ff; //这里可以直接写入方法。
ffdelegate("最初最简单的,");
//使用匿名方法。。
helloWorld sedelegate = delegate(string name) { Console.WriteLine(name+",你好!"); };
sedelegate("匿名方法");
//使用拉姆达表达式
helloWorld thdelegate = (p => { Console.WriteLine(p+",你好"); });
thdelegate("拉姆达表达式");
//使用Action
Action<string> fordelegate=(p=>{Console.WriteLine(p+",你好!");});
fordelegate("Action");
//使用Func
Func<string, string> fidelegate = (p => p + ",你好!");
string sayHello = fidelegate("Func");
Console.WriteLine(sayHello);
Console.ReadKey();
}
public void ff(string name)
{
Console.WriteLine(name+"你好!");
}
}
4.事件的使用
事件是一种使对象或类能够提供通知的成员,其实也是一种特殊类型的委托。他包含两个参数:指示事件源的“对象源”参数和封装事件的其他任何相关信息的e参数。其中,e参数的类型为system.EventArgs类型或从这类型中派生的类型。
1.事件的简单认识
namespace 事件
{
public delegate void GreetingDelegate(string name); //声明委托
class Program
{
private static void ChineseGreeting(string name) //定义事件处理程序
{
Console.WriteLine("你好, " + name);
}
static void Main(string[] args)
{
GreetingManager gm = new GreetingManager();
gm.MakeGreet += ChineseGreeting; //订阅事件(将事件处理程序添加到事件的调用列表中)
gm.GreetPeople("事件!");
Console.ReadKey();
}
}
public class GreetingManager
{
public event GreetingDelegate MakeGreet; //声明一个事件,event为声明事件的关键字,其实事件是一种特殊类型的委托
public void GreetPeople(string name)
{
MakeGreet(name); //把这里的事件看做一个委托来理解,更容易点。
}
}
}
2.事件的应用 (Observer设计模式--热水器)
using System;
using System.Collections.Generic;
using System.Text;
namespace Delegate {
// 热水器
public class Heater {
private int temperature;
public string type = "RealFire 001"; // 添加型号作为演示
public string area = "China Xian"; // 添加产地作为演示
//声明委托
public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e);
public event BoiledEventHandler Boiled; //声明事件
// 定义BoiledEventArgs类,传递给Observer所感兴趣的信息
public class BoiledEventArgs : EventArgs {
public readonly int temperature;
public BoiledEventArgs(int temperature) {
this.temperature = temperature;
}
}
// 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视
protected virtual void OnBoiled(BoiledEventArgs e) {
if (Boiled != null) { // 如果有对象注册
Boiled(this, e); // 调用所有注册对象的方法
}
}
// 烧水。
public void BoilWater() {
for (int i = 0; i <= 100; i++) {
temperature = i;
if (temperature > 95) {
//建立BoiledEventArgs 对象。
BoiledEventArgs e = new BoiledEventArgs(temperature);
OnBoiled(e); // 调用 OnBolied方法
}
}
}
}
// 警报器
public class Alarm {
public void MakeAlert(Object sender, Heater.BoiledEventArgs e) {
Heater heater = (Heater)sender; //这里是不是很熟悉呢?
//访问 sender 中的公共字段
Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type);
Console.WriteLine("Alarm: 嘀嘀嘀,水已经 {0} 度了:", e.temperature);
Console.WriteLine();
}
}
// 显示器
public class Display {
public static void ShowMsg(Object sender, Heater.BoiledEventArgs e) { //静态方法
Heater heater = (Heater)sender;
Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type);
Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", e.temperature);
Console.WriteLine();
}
}
class Program {
static void Main() {
Heater heater = new Heater();
Alarm alarm = new Alarm();
heater.Boiled += alarm.MakeAlert; //注册方法
heater.Boiled += (new Alarm()).MakeAlert; //给匿名对象注册方法
heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert); //也可以这么注册
heater.Boiled += Display.ShowMsg; //注册静态方法
heater.BoilWater(); //烧水,会自动调用注册过对象的方法
}
}
}
输出为:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Display:China Xian - RealFire 001:
Display:水快烧开了,当前温度:96度。
// 省略 ...


浙公网安备 33010602011771号