C#中的委托和事件 – Part.1 – 技术

2007-9-23混合物: C# 使假释出狱

译文正中鹄的行为准则短暂拜访在VS2005下,鉴于VS2003(.NET Framework 1.1)不支持隐式的委托变量,因而条件在一任一某一接收委托典型的使实现预期的结果座位直接的付与办法名,会有一任一某一错误的在VS2003,清算条件是显式的到达一任一某一委托典型的探察(委托变量)。诸如:委托典型 委托探察 = new 委托典型(办法名);

小引

委托 和 事变 .Net 组织正中鹄的器具特有的普遍。,不论到什么程度,较好地理解委托和事变对很多门路C#时期不长的人来说绝不轻易。他们就像一任一某一窗台。,走过窗台的人,想起很轻易,而缺乏过来的人每回注视委托和事变就觉得心别(biè)得慌,混身惴惴不安。本贴壁纸,我将短暂拜访两个特例由浅入深地详细叙述是什么委托、为什么要应用委托、事变的前兆、.Net Framework正中鹄的委托和事变、委托和事变对Observer设计调式的意思,当中行为准则也停止了议论。。

以办法为决定因素

本人非物质的即将到来的题目。,也不是论委托终究是个什么东西,看一眼这两种最复杂的办法,他们只不外在银幕上说了一句欢迎辞。:

public void GreetPeople(string 的名字) {
// 做某一额定的事实,诸如,设定初值等。,在这里较宽容的
EnglishGreeting(的名字);
}
public void EnglishGreeting(string 的名字) {
(晚上, ” + 的名字);
}

无论健康状况如何这两种办法是什么,都缺乏实践意思。。greetpeople用来向有人向某人欢迎辞,当本人传送名为name的name决定因素时,诸如,吉米,当你上的时辰,在该办法中,的englishgreeting办法将被转让,再次传送据以取名决定因素,englishgreeting用来出口到银幕 “Morning, Jimmy”。

现时以为即将到来的挨次需求全球化。,哎呀,这不好,讲中国人的,,我不懂晚上是什么意思。,你是做以此类推?好吧,本人再加个中文版的欢迎辞办法:

public void ChineseGreeting(string 的名字){
(早安), ” + 的名字);
}

这时辰,greetpeople也需求交替,独的健康状况如何判别终于用哪个版本的Greeting欢迎辞办法马上呢?在停止即将到来的先发制人,本人最好构成释义一任一某一计数作为判别的本着。:

public enum Language{
English, Chinese
}

public void GreetPeople(string name, Language 朗)
//做某一额定的事实,诸如,设定初值等。,在这里较宽容的
swith(朗)
case Language.English:
EnglishGreeting(的名字);
break;
case Language.Chinese:
ChineseGreeting(的名字);
break;
}
}

OK,尽管如此,成绩左右处理了。,但我不以为这是轻易忆起的。,此处理训练的可伸缩性特有的差。,条件今后本人需求再添加韩文版、日文版,就不得不反转修正计数和GreetPeople()办法,适合于新的需求。

在思索新的处理训练先发制人,让本人先看一眼。 greetpeople署名的办法:

public void GreetPeople(string name, Language 朗)

本人只看它 string name,在在这里,string 是决定因素的典型。,name 它是一任一某一决定因素变量。,当本人将字母串命名为吉米时,它代表了吉米的值得的。;当本人把它给它张子阳,它也代表了张子阳的值得的。。后来地,本人可以在办法体内对即将到来的name停止对立面动手术。哎,这只不外无意义的吗?,刚学了即将到来的挨次。。

条件你再思索一下,条件GreetPeople()办法接收一任一某一决定因素变量,即将到来的变量可以表现备选的办法。,当本人为即将到来的变量赋一任一某一值时 对englishgreeting时期,它代表 EnglsihGreeting() 即将到来的办法;当本人把它分比例chinesegreeting 的时辰,它也代表了ChineseGreeting()办法。本人将即将到来的决定因素变量命名为 MakeGreeting,因而它不像是分比例名字的。,在转让 该greetpeople时期()办法,把这makegreeting 决定因素也赋上值么(ChineseGreeting或许EnglsihGreeting等)?后来地,本人挡着人体细胞的路。,你可以应用makegreeting也对立面决定因素。不管怎样,由于makegreeting表现办法,它的应用方法必不可少的事物和它被赋的办法(譬如ChineseGreeting)是两者都的,譬如:

MakeGreeting(的名字);

好了,有一种心理方法,本人麝香交替本人的办法(greetpeople),那必不可少的事物是它看起来好像的惯例。:

public void GreetPeople(string name, *** MakeGreeting){
MakeGreeting(的名字);
}

理睬到 *** ,即将到来的使实现预期的结果座位的使实现预期的结果座位必不可少的事物是决定因素的典型。,但到眼前为止,本人只不外以为必不可少的事物有一任一某一决定因素来表现办法。,重写的greetpeople办法依照即将到来的思绪,现时有个大成绩:这必不可少的事物makegreeting什么典型的决定因素表现的办法吗?

不再需求倾斜,由于该办法恒稳态决定分派makegre时应用,这是ChineseGreeting或 EnglishGreeting,在这两种办法里面,在应用早或早安中间有分开。。

你必不可少的事物忆起的情报,现时是委托该参加的时辰了,但详细叙述委托先发制人,让本人在makegreeting决定因素看。 ChineseGreeting()和EnglishGreeting()办法的署名:

public void EnglishGreeting(string 的名字)
public void ChineseGreeting(string 的名字)

鉴于据以取名可以接收true和1的字母串典型。,不管怎样你不克不及接收原封不动的异样的典型的乔治英国数学家和逻辑学家典型为真实和int典型1。MakeGreeting的 决定因素典型构成释义 它必不可少的事物能决定 典型的办法,makegreeting可以代表,再而且讲,这是makegreeting表现办法 的 决定因素典型和重行提起典型。

立即,委托涌现了:它构成释义了典型的办法,makegreeting决定因素可以代表,是的makegreeting决定因素的典型。

条件上面的句子是拂,我把它翻译成非常的:string 构成释义可以表现的据以取名决定因素。典型的值,这是name决定因素的典型。。

本例中委托的构成释义:

public delegate void GreetingDelegate(string 的名字);

你可以相比的englishgreeting署名()办法,要责任添加委托保存字要责任,其余者的原封不动的两者都吗?

现时,让本人交替greetpeople()办法,列举如下所示:

public void GreetPeople(string name, GreetingDelegate MakeGreeting){
MakeGreeting(的名字);
}

如你所见,委托GreetingDelegate涌现的使实现预期的结果座位与 字母串相等的数量,字母串是一种典型。,因而greetingdelegate必不可少的事物是一任一某一典型为好,或称为类(类)。不管怎样委托的资格方法和类却原封不动的多种多样的,怎地回事呢?说起来,,委托在编辑的时辰确凿会编辑成类。由于委托是一任一某一类,因而在轻轻地可以资格类的使分裂都可以资格委托。上面将表现更多使满足。,现时,请看即将到来的探察的原封不动的行为准则。:

using System;
using System.Collections.Generic;
using System.Text;

namespace Delegate {

//构成释义委托,它构成释义了可以表现的办法的典型。
public delegate void GreetingDelegate(string 的名字);

class Program {

private static void EnglishGreeting(string 的名字) {
(晚上, ” + 的名字);
}

private static void ChineseGreeting(string 的名字) {
(早安), ” + 的名字);
}

理睬即将到来的办法,它接收一任一某一greetingdelegate型办法作为一任一某一决定因素
private static void GreetPeople(string name, GreetingDelegate MakeGreeting) {
MakeGreeting(的名字);
}

static void 次要(字母串 args) {
GreetPeople(吉米 Zhang”, EnglishGreeting);
GreetPeople(张子阳), ChineseGreeting);
();
}
}
}

出口列举如下:
Morning, Jimmy Zhang
早安, 张子阳

本人现时对委托做一任一某一总结:

委托是一任一某一类,它构成释义了办法的典型。,容许将办法作为另一办法的决定因素传送,恒稳态分派决定因素的办法,在少量挨次中,您可以幸免应用if(关闭电流)表现。,同时,该训练具有较好的可扩展性。。

将办法绑定到委托

瞥见在这里,即使短时间如梦初醒的觉得?,你在想吗?:在上面的探察中,我缺乏给它直接的向greetpeople()办法 据以取名决定因素评价,我可以用非常的的变量:

static void 次要(字母串 args) {
string name1, name2;
name1 = “Jimmy Zhang”;
name2 = “张子阳”;

GreetPeople(name1, EnglishGreeting);
GreetPeople(name2, ChineseGreeting);
();
}

而既然委托GreetingDelegate 和 典型 string 异样的使实现预期的结果座位,它们都构成释义了一任一某一决定因素典型。,这样地,讲责任也可以这样地应用委托?

static void 次要(字母串 args) {
GreetingDelegate delegate1, delegate2;
delegate1 = EnglishGreeting;
delegate2 = ChineseGreeting;

GreetPeople(吉米 Zhang”, delegate1);
GreetPeople(张子阳), delegate2);
();
}

正像你所意料的,没成绩。,挨次出口如预支。。在这里,我以为说的是委托多种多样的于string的一任一某一特点:可以将多个办法赋给原封不动的异样的任一某一委托,或许叫将多个办法绑定到原封不动的异样的任一某一委托,当转让即将到来的委托的时辰,绑定的办法将先后转让。。在即将到来的探察中,用语列举如下:

static void 次要(字母串 args) {
GreetingDelegate delegate1;
delegate1 = EnglishGreeting; // 先给委托典型的变量评价
delegate1 += ChineseGreeting; // 给此委托变量再绑定一任一某一办法

// 将先后转让 EnglishGreeting 与 ChineseGreeting 办法
GreetPeople(吉米 Zhang”, delegate1);
();
}

出口为:
Morning, Jimmy Zhang
早安, Jimmy Zhang

实践的,本人可以圆形的greetpeople办法,短暂拜访委托来直接的转让EnglishGreeting和ChineseGreeting:

static void 次要(字母串 args) {
GreetingDelegate delegate1;
delegate1 = EnglishGreeting; // 先给委托典型的变量评价
delegate1 += ChineseGreeting; // 给此委托变量再绑定一任一某一办法

// 将先后转让 EnglishGreeting 与 ChineseGreeting 办法
delegate1 (吉米 张)
();
}

在这种情况下,这责任成绩。,但匍匐生根的看一眼在GreetPeople的构成释义,在它在内的可以做某一到某种财产EnglshihGreeting和ChineseGreeting来说都需求停止的任务,为了复杂起见,我做了省略。。

理睬即将到来的,头等用的“=”,是作业的用语吗?;瞬间次,应用的是,是绑定用语。。条件你头等应用它,一任一某一编辑错误的,应用未分派的分离变量将涌现。

本人还可以应用上面的行为准则来理想化即将到来的褶皱:

GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);
delegate1 += ChineseGreeting; // 给此委托变量再绑定一任一某一办法

瞥见在这里,必不可少的事物理睬到,即将到来的行为准则的第一任一某一陈说和努力生中间的类似地之处是什么?,你禁不住想:上面头等绑定委托时不可以应用“+=”的编辑错误的,或许非常的可以幸免。:

GreetingDelegate delegate1 = new GreetingDelegate();
delegate1 += EnglishGreeting; // 这次是用的。 “+=”,绑定用语。
delegate1 += ChineseGreeting; // 给此委托变量再绑定一任一某一办法

但说起来,这将领到编辑错误的。: greetingdelegate的办法是缺乏用的0”决定因素重担。即使即将到来的水果让本人短时间灰心的。,不管怎样编辑心情:“缺乏0决定因素重担”再次让本人联忆起了类的建筑的功能。我实施你会被吊胃口去探究发作了什么,但在那先发制人,本人需求先绍介一下初步和器具。。

既然给委托可以绑定一任一某一办法,后来地必不可少的事物有一种办法移居对办法的绑定。,很轻易忆起,这种用语:

static void 次要(字母串 args) {
GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);
delegate1 += ChineseGreeting; // 给此委托变量再绑定一任一某一办法

// 将先后转让 EnglishGreeting 与 ChineseGreeting 办法
GreetPeople(吉米 Zhang”, delegate1);
();

delegate1 -= EnglishGreeting; 移居绑定到englishgreeting办法
// 将只高级的 ChineseGreeting
GreetPeople(张子阳), delegate1);
();
}
出口为:
Morning, Jimmy Zhang
早安, Jimmy Zhang
早安, 张子阳

让本人再次对委托作个总结:

应用委托可以将多个办法绑定到原封不动的异样的任一某一委托变量,当转让即将到来的变量时(在这里应用了转让一词)。,由于即将到来的变量表现一种办法。,可以先后转让全部绑定。。

事变的前兆

本人持续深思上面的挨次。:前述事项三个办法是在类中构成释义的挨次,这是为了便于理解。,实践器具中,它通常是 GreetPeople 在一任一某一班,ChineseGreeting和 EnglishGreeting 在另一任一某一类。现时你早已对委托受胎初步理解,该是对上面的探察停止改善的时辰了。。以为本人将GreetingPeople()放在一任一某一叫GreetingManager的类中,因而新挨次必不可少的事物是非常的的:

namespace Delegate {
//构成释义委托,它构成释义了可以表现的办法的典型。
public delegate void GreetingDelegate(string 的名字);

新的greetingmanager类
public class GreetingManager{
public void GreetPeople(string name, GreetingDelegate MakeGreeting) {
MakeGreeting(的名字);
}
}

class Program {
private static void EnglishGreeting(string 的名字) {
(晚上, ” + 的名字);
}

private static void ChineseGreeting(string 的名字) {
(早安), ” + 的名字);
}

static void 次要(字母串 args) {
// … …
}
}
}

即将到来的时辰,条件您想实施先前演示的出口胜利,我以为必不可少的事物采用的次要办法是。:

static void 次要(字母串 args) {
GreetingManager gm = new GreetingManager();
(吉米 Zhang”, EnglishGreeting);
(张子阳), ChineseGreeting);
}

本人运转即将到来的行为准则,嗯,缺乏轻轻地成绩。挨次出口如预支。:

Morning, Jimmy Zhang
早安, 张子阳

现时,以为本人需求应用至死一节所学到的经验教训。,将多个办法绑定到原封不动的异样的任一某一委托变量,本人必不可少的事物怎地做?让本人重写行为准则。:

static void 次要(字母串 args) {
GreetingManager gm = new GreetingManager();
GreetingDelegate delegate1;
delegate1 = EnglishGreeting;
delegate1 += ChineseGreeting;

(吉米 Zhang”, delegate1);
}

出口:
Morning, Jimmy Zhang
早安, Jimmy Zhang

到了在这里,本人禁不住深思。:承认男朋友设计,它是涉及男朋友的封装。,既然可以资格委托典型的变量(在上例中是delegate1),本人为什么不封装即将到来的变量呢? GreetManager类中?在即将到来的类的客户端中应用责任更便宜么?立即,本人重写了greetmanager类,像非常的:

public class GreetingManager{
//在GreetingManager类的内脏资格delegate1变量
public GreetingDelegate delegate1;

public void GreetPeople(string name, GreetingDelegate MakeGreeting) {
MakeGreeting(的名字);
}
}

现时,本人可以非常的应用即将到来的委托变量:

static void 次要(字母串 args) {
GreetingManager gm = new GreetingManager();
= EnglishGreeting;
+= ChineseGreeting;

(吉米 Zhang”, );
}

出口为:
Morning, Jimmy Zhang
早安, Jimmy Zhang

尽管如此,缺乏成绩。,但本人查明这种用语很惊人的。。转让该办法时,通用汽车的delegate1场再传:

(吉米 Zhang”, );

在这种情况下,本人为什么不交替它呢? GreetingManager 类成非常的:

public class GreetingManager{
//在GreetingManager类的内脏资格delegate1变量
public GreetingDelegate delegate1;

public void GreetPeople(string 的名字) {
if(delegate1!null) //条件有办法登记委托变量
delegate1(的名字); //短暂拜访委托转让办法
}
}
}

在客户端,即将到来的工具看起来好像更简约。:

static void 次要(字母串 args) {
GreetingManager gm = new GreetingManager();
= EnglishGreeting;
+= ChineseGreeting;

(吉米 张) //理睬,这次不需求转变。 delegate1变量
}

出口为:
Morning, Jimmy Zhang
早安, Jimmy Zhang

即使这早已实现了本人祝福的胜利。,但依然在一任一某一成绩。:

在在这里,delegate1无干变量的字母串典型,本人通常应用的,本人实施,并非全部接都必不可少的事物户外资格,正常的的做法是,大众必不可少的事物是大众的。,当公家被以为是公家的。

让本人先看一眼。条件把 delegate1 资格 公家将是什么?其水果是:只不外好玩的罢了。。由于资格委托的客观的执意为了把它揭露在类的客户端停止办法的登记,你把它资格private了,客户端使固定看不到它。,这样地它同样什么用处呢?

再看一眼delegate1 资格 public 会是什么?其水果是:客户机可以在客户机上家具恣意分派。,下场损坏男朋友的封装。

至死,第一种登记办法,是评价文法吗?,由于探察化,瞬间个办法登记则应用的是。不管怎样,不即使分派或登记管道,都是将办法绑定到委托上,要责任工具要责任,定单也不是两者都。,缺乏分开。,那不适吗?

现时让本人思索一下。,条件delegate1责任一任一某一委托典型,这是字母串典型。,你会怎地做?答案是应用属性来封装接。。

立即,事变出版,它封装了委托典型的变量,使得:在类的内脏,无论健康状况如何您资格它是公共的左右受庇护的,它常常公家的。教室外,登记“+=”和吊销“-=”的提问限符与你在资格事变时应用的提问符相等的数量。

本人重写了greetingmanager类,样板是非常的的。:

public class GreetingManager{
这次本人是来宣告一任一某一事变的。
public event GreetingDelegate MakeGreet;

public void GreetPeople(string 的名字) {
MakeGreet(的名字);
}
}

这很轻易被理睬到。:MakeGreet 事变的资格与先发制人委托变量delegate1的资格不料的分开是多了一任一某一event保存字。瞥见在这里,并有是你这么说的嘛!解说,你必不可少的事物显著的:这件事缺乏什么可理解的。,资格一任一某一事变不外类似地资格一任一某一停止了封装的委托典型的变量罢了。

使发誓前述事项推断,条件本人重写非常的的main办法:

static void 次要(字母串 args) {
GreetingManager gm = new GreetingManager();
gm.MakeGreet = EnglishGreeting; // 编辑错误的1
gm.MakeGreet += ChineseGreeting;

(吉米 张)
}

将实现预期的结果编辑错误的。:事变但是涌现时事变中。 += 或 -= 在左翼(要责任在典型中应用)。

事变和委托的编辑行为准则

这时辰,本人对编辑错误的的行停止正文。,后来地重行编辑,跟随反照的帮忙 事变的资格表现是一任一某一乐器等被奏响。,看一眼为什么这是个错误的。:

public event GreetingDelegate MakeGreet;

可以瞥见,说起来,即使本人会在greetingmanager MakeGreet 资格public,不管怎样,说起来,makegreet将编辑成 公有接,可宽恕的这将是一任一某一编辑错误的。,由于它使固定就不容许在GreetingManager类的里面以评价的方法提问,相应地证明本人在上面所作的推断。。

让本人makegreet行为准则发生的而且努力:

private GreetingDelegate MakeGreet; 事变的陈说 实践是 资格一任一某一公有的委托变量

[MethodImpl()]
public void add_MakeGreet(GreetingDelegate 值)
this.MakeGreet = (GreetingDelegate) (this.MakeGreet, 值)
}

[MethodImpl()]
public void remove_MakeGreet(GreetingDelegate 值)
this.MakeGreet = (GreetingDelegate) (this.MakeGreet, 值)
}

现时很明亮的了。:MakeGreet事变确凿是一任一某一GreetingDelegate典型的委托,只不外不论即使资格public,它常常被资格private。独,有两种办法可以做。,他们add_makegreet和remove_makegreet,分开。,这两个办法分开用于登记委托典型的办法和移居登记。说起来,它是: “+= ”对应 add_MakeGreet,对应remove_makegreet。这两种办法的提问限度局限安心提问限度局限。。

在add_makegreet()办法,实践的称为轧()恒稳态办法。,即将到来的办法用于将容易的变量添加到委托链表中。本人先发制人提到过两遍。,说委托实践的是一任一某一类,在本人构成释义委托的时辰:

public delegate void GreetingDelegate(string 的名字);

当编辑器碰见此行为准则时,将产生物理反应以下原封不动的类:

public sealed class GreetingDelegate:{
public GreetingDelegate(object @object, IntPtr 办法)
public virtual IAsyncResult Begin转让(字母串 name, AsyncCallback callback, object 男朋友)
public virtual void EndInvoke(IAsyncResult 水果)
public virtual void 转让(字母串 的名字);
}

涉及即将到来的类更深化的使满足,见CLR Via C #等互插书,在这里不再议论了。。

委托、事变与观测器设计调式

探察的表现

前述事项的探察信心不足的解说上面的解说,让本人在新的探察看,由于早已引入了很多使满足。,因而即将到来的教派的票价会快稍许的。:

以为本人有高档热水器,本人给它电,当水温超越95度时:1、讲人将开端讲。,告知你水的发烧;2、液晶显示也交替水温显示。,线索水在电子书宣读器。。

现时本人需求排一任一某一挨次来模仿水的电子书宣读器褶皱。,本人将构成释义一任一某一类来表现热水器。,本人称之为工具:Heater,它有代表水温的接。,这叫发烧。;自然,同样一任一某一必要的的水暖气装置办法BoilWater,一种发送语音提示,MakeAlert,显示水温的一种办法,ShowMsg()。

namespace Delegate {
class Heater {
private int temperature; // 水温
// 烧水
public void BoilWater() {
for (int i = 0; i <= 100; i++) { temperature = i; if (temperature > 95) {
MakeAlert(发烧);
ShowMsg(发烧);
}
}
}

// 收回给配上声部警报
private void MakeAlert(int 决定因素) {
(告警:哔哔声,水早已 {0} 度了:” , 决定因素);
}

// 显示水温
private void ShowMsg(int 决定因素) {
(显示:水开得很快。,容易发烧:{0}度。” , 决定因素);
}
}

class Program {
static void Main() {
Heater ht = new Heater();
();
}
}
}

浅谈值班员的设计调式

上面的探察明亮的地阐明了本人后面的表现。,但这还不敷好。。现时以为热水器是由三教派结合的。:热水器、警报器、广袤,他们因为多种多样的的供应国并安置。。这样地,必不可少的事物是热水器只正大光明烧水,它不熟练的收回警报,也不是克不及显示水温。;当水被烧开,警报器收回警报、广袤显示水温。

这时辰,上面的探察必不可少的事物适合即将到来的:

// 热水器
public class Heater {
private int temperature;

// 烧水
private void BoilWater() {
for (int i = 0; i <= 100; i++) { temperature = i; } } } // 警报器 public class Alarm{ private void MakeAlert(int 决定因素) { (告警:哔哔声,水早已 {0} 度了:" , 决定因素); } } // 广袤 public class Display{ private void ShowMsg(int 决定因素) { (显示:水已烧开,容易发烧:{0}度。" , 决定因素); } }

在这里有个成绩。:当水被引起时健康状况如何传单告警和班长?在它散去先发制人,让本人先看一眼值班员设计调式。,值班器设计调式包孕以下两类男朋友:

  1. Subject:监督男朋友,它通常容纳对立面男朋友感兴趣的使满足。。在即将到来的探察中,热水器执意一任一某一监督男朋友,它容纳了对立面男朋友感兴趣的使满足。,它的发烧场,当该接的值为100时,材料不休地发使作出监督它的男朋友。。
  2. Observer:监督者,它监控即将到来的提出。,当有点发作时,告知值班员,值班员将采用行为。。在即将到来的探察中,值班员有警报器和班长。,他们采用的行为是提示和显示水温,分开。

在本例中,事实发作的挨次必不可少的事物是非常的:

  1. 告警器和班长告知热水器。,它感兴趣的是它的发烧相比(登记)。。
  2. 热水器实施后保存对警报器和广袤的援用。
  3. 热水器电子书宣读器水的功能,当水温超越95度时,短暂拜访告警和显示,MakeAlert()不假思索的工具告警办法、的showmsg()的显示办法。

像非常的的探察很多。,GoF抽象派的。,称为观测器设计调式:观测器设计调式用于构成释义一对多信任相干。,助长实质财产的交替,对立面信任于它的男朋友将不假思索的传单和修正。。值班器调式是一种松耦合的设计调式。。

用于实施示例的值班器设计调式

本人先发制人早已对委托和事变绍介很多了,现时写行为准则必不可少的事物很轻易。,现时直接的在在这里作出行为准则。,并在正文中阐明。

using System;
using System.Collections.Generic;
using System.Text;

namespace Delegate {
// 热水器
public class Heater {
private int temperature;
public delegate void BoilHandler(int 决定因素); //资格委托
public event BoilHandler BoilEvent; 资格事变

// 烧水
public void BoilWater() {
for (int i = 0; i <= 100; i++) { temperature = i; if (temperature > 95) {
if (BoilEvent != null) { 条件有男朋友登记
BoilEvent(发烧); 转让全部登记男朋友的办法
}
}
}
}
}

// 警报器
public class Alarm {
public void MakeAlert(int 决定因素) {
(告警:哔哔声,水早已 {0} 度了:”, 决定因素);
}
}

// 广袤
public class Display {
public static void ShowMsg(int 决定因素) { //恒稳态办法
(显示:水在电子书宣读器。,容易发烧:{0}度。”, 决定因素);
}
}

class Program {
static void Main() {
Heater heater = new Heater();
Alarm alarm = new Alarm();

heater.BoilEvent += ; //登记办法
heater.BoilEvent += (新 Alarm()).MakeAlert; 隐姓埋名男朋友登记办法
heater.BoilEvent += Display.ShowMsg; 登记恒稳态办法

(); //烧水,不假思索的转让登记男朋友的办法
}
}
}

出口为:
Alarm:哔哔声,水早已 96 度了:
Alarm:哔哔声,水早已 96 度了:
Display:水在电子书宣读器。,容易发烧:96度。
// 省略.

.Net Framework正中鹄的委托与事变

即使上面的探察十足好,可以做本人想做的事实。,但本人不光仅是困惑糊涂的。:为什么.Net Framework 事变模式和上面的有什么分开?为什么会有M?

在答复前述事项成绩先发制人,本人率先理解 .Net 组织行为准则准则:

  • 委托典型的据以取名都必不可少的事物以EventHandler完毕。
  • 委托的原模式构成释义:有一任一某一失效的重行提起值。,并接收两个输出决定因素:一任一某一男朋友 典型,一任一某一 EventArgs典型(或成功自EventArgs)。
  • 事变的据以取名是 委托完全屈从于压制 剩的教派短暂拜访EventHandler。
  • 典型成功自EventArgs必不可少的事物完毕的事变。

作瞬间解说:

  1. 委托资格原模式正中鹄的Object典型的决定因素代表了Subject,也执意监督男朋友,在这种情况下,它是 暖气装置器(热水器)。回调功能(譬如Alarm的MakeAlert)可以短暂拜访它提问引起事变的男朋友(Heater)。
  2. EventArgs 男朋友容纳值班员感兴趣的材料。,在这种情况下,它是temperature。

这些不光仅是用于编码准则。,这也使得挨次全部情况敏捷。。譬如说,条件本人不情愿记录热水器的发烧,也愿望在值班端(警报或显示)实现预期的结果它的出厂日期。、模特儿、价钱,这样地委托和办法的资格首都变得很折磨,条件本人把热水器的援用传给告警器,热水器可以直接的进入该办法。。

现时本人重写了后面的探察。,让它适合于 .Net Framework 的准则:

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类构成释义,传使作出值班员的通信
public class BoiledEventArgs : EventArgs {
public readonly int temperature;
public BoiledEventArgs(int 发烧) {
this.temperature = temperature;
}
}

// 可以成功 Heater 类重写,从此成功类回绝由对立面男朋友监督它。
protected virtual void OnBoiled(煮EventArgs e) {
if (煮 != null) { // 条件有男朋友登记
煮(这, e); // 转让全部登记男朋友的办法
}
}

// 烧水。
public void BoilWater() {
for (int i = 0; i <= 100; i++) { temperature = i; if (temperature > 95) {
树立boiledeventargs 男朋友。
BoiledEventArgs e = new BoiledEventArgs(发烧);
OnBoiled(e); // 转让 OnBolied办法
}
}
}
}

// 警报器
public class Alarm {
public void MakeAlert(Object sender, Heater.BoiledEventArgs e) {
Heater heater = (暖气装置器)发送器 在这里熟识吗?
//提问 sender 郊野里的公共田地
(告警:{0} – {1}: “, heater.area, heater.type);
(告警: 哔哔声,水早已 {0} 度了:”, );
();
}
}

// 广袤
public class Display {
public static void ShowMsg(Object sender, Heater.BoiledEventArgs e) { //恒稳态办法
Heater heater = (暖气装置器)发送器
(显示:{0} – {1}: “, heater.area, heater.type);
(显示:水在电子书宣读器。,容易发烧:{0}度。”, );
();
}
}

class Program {
static void Main() {
Heater heater = new Heater();
Alarm alarm = new Alarm();

heater.Boiled += ; //登记办法
heater.Boiled += (新 Alarm()).MakeAlert; 隐姓埋名男朋友登记办法
heater.Boiled += new Heater.BoiledEventHandler(); 你也可以登记即将到来的
heater.Boiled += Display.ShowMsg; 登记恒稳态办法

(); //烧水,不假思索的转让登记男朋友的办法
}
}
}

出口为:
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度。
// 省略 …

总结

在本贴壁纸我率先短暂拜访一任一某一GreetingPeople的小挨次向全部情况绍介了委托的向某人点头或摇头示意、委托用来做什么,后来地事变发作了。,接住对委托与事变所发生的当中行为准则做了粗略的详细叙述。

以瞬间个轻轻地复杂的热水器为例,我给你做了复杂的绍介。 Observer设计调式,短暂拜访实施即将到来的模式早已取得了即将到来的调式。,后来地它告知。 Framework中委托、事变的实施。

谢谢你的宣读,我愿望定冠词能对你有所帮忙。!

发表评论

电子邮件地址不会被公开。 必填项已用*标注