委托和事件

合集下载

委托和事件的区别

委托和事件的区别

委托和事件的区别委托的本质,是⼀个类,⽽事件,是⼀个委托类型的私有变量加上两个公有⽅法(事件的+=和-=),这是本质区别。

打个⽐⽅,string 也是⼀个类,⽽string s = "a",这个s是string类型的⼀个变量(略有不恰当,为了⽅便直观理解)。

public delegate void myDel();相当于你创建了⼀个myDel的类,所以委托可以在任何地⽅创建,类需要实例化,所以委托需要实例化,要myDel m = ……;申明⼀个事件 public event myDel myEvent;事件myEvent是⼀个myDel类型的⼀个变量,因为是变量,所以事件只能在类⾥⾯申明,不需要实例化,有点类似与上⾯的那个m,当然不全是,他还有两e79fa5e98193e4b893e5b19e31333366306531个⽅法(+=,-=),调⽤⼀次+=⽅法,myEvent += MethodA;其实是把MethodA⽅法,封装成⼀个myDel类型的委托对象,然后把这个对象的引⽤赋值给这个myEvent变量。

如果多次调⽤+=,就是多个⽅法封装成了多个myDel委托对象,然后这些委托对象放在⼀个列表⾥⾯,然后myEvent就指向这个列表,触发的时候,就是调⽤这个列表⾥⾯的所有委托的Invoke⽅法。

转delegate是C#中的⼀种类型,它实际上是⼀个能够持有对某个⽅法的引⽤的类。

与其它的类不同,delegate类能够拥有⼀个签名(signature),并且它"只能持有与它的签名相匹配的⽅法的引⽤"。

它所实现的功能与C/C++中的函数指针⼗分相似。

它允许你传递⼀个类A的⽅法m给另⼀个类B的对象,使得类B的对象能够调⽤这个⽅法m。

但与函数指针相⽐,delegate有许多函数委托和事件在 .Net Framework中的应⽤⾮常⼴泛指针不具备的优点。

⾸先,函数指针只能指向静态函数,⽽delegate既可以引⽤静态函数,⼜可以引⽤⾮静态成员函数。

C#基础知识学习之?委托(delegate)与事件(event)之间的介绍

C#基础知识学习之?委托(delegate)与事件(event)之间的介绍

C#基础知识学习之✨委托(delegate)与事件(event)之间的介绍委托(delegate) 与事件(event)前言在之前的文章里介绍了C#中的委托(delegate)(Action、Func、Predicate)的基本含义及用法那本篇文章在这里还要介绍一个跟委托有很大关系的小伙伴——C#中的事件(event)事件跟委托是有很大联系的,所以也就导致很容易分不清他们两个,以及什么时候用这两个上面有博客提到委托,想单独了解委托的可以去看一下,本篇文章主要说一下什么是事件以及事件与委托的区别委托和事件的定义委托在这里再说一遍委托跟事件的简单定义(没有搜到特别准确的,都是大概定义,理解万岁)委托:delegate 是一种可用于封装命名或匿名方法的引用类型。

委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。

委托是一种动态调用方法的类型,属于引用型。

委托是对方法的抽象和封装。

委托对象实质上代表了方法的引用(即内存地址)委托允许将方法作为参数进行传递。

委托可用于定义回调方法。

委托可以把多个方法链接在一起。

这样,在事件触发时可同时启动多个事件处理程序。

委托签名不需要与方法精确匹配。

事件事件:事件是特殊类型的多路广播委托,仅可从声明它们的类或结构(发行者类)中调用。

如果其他类或结构订阅了该事件,则当发行者类引发该事件时,会调用其事件处理程序方法。

事件表示C#中已定义的一个对象,即处理通知过程的对象通常,每个事件的发生都会产生发送方和接收方。

在.net框架中,事件是将事件发送者(触发事件的对象)与事件接受者(处理事件的方法)相关联的一种代理类,即事件机制是通过代理类来实现的。

当一个事件被触发时,由该事件的代理来通知(调用)处理该事件的相应方法委托和事件的区别简单说了一下两者的定义,眼神好的小伙伴这时候就会发现,事件的说明里有提到一句话:“事件也可以算一种特殊的委托”,这句话不是特别准确,但是也不妨可以这样理解。

Unity+C#游戏开发接口,委托与事件

Unity+C#游戏开发接口,委托与事件

游戏开发第五章接口,委托与目录 CONTENTS五.一接口零一五.二委托零二五.三零三内容简述"接口"理解为就是定义一套标准,然后由实现类来具体实现其地方法,接口就是一组类地抽象。

"委托"理解为"方法地抽象",也就是说定义一个方法地模板,至于这个方法具体是怎么样地,就由方法自己去实现。

是用户操作,例如:按键,点击,鼠标移动等。

或者某些,例如:系统生成地通知。

应用程序需求响应发生时。

五.一接口接口(interface)是C#地一种数据类型,属于引用类型。

一个接口定义一个协定。

接口可以包含方法,属,与索引器,接口本身不提供它所定义地成员地实现,接口只指定实现该接口地类或结构需要提供地成员。

实现某接口地类需要遵守该接口定义地协定,即需要提供接口成员地实现。

五.一.一 . 接口地定义一.定义接口是指定一组函数成员而不实现成员地引用类型,其它类型与接口可以继承接口。

二.特点通过接口可以实现多重继承,接口里面地方法都需求由外面接口实现去实现方法体,那么其修饰符必然是public。

接口成员不能有new,static,abstract,override,virtual修饰符。

接口只包含成员地签名,接口没有构造函数,所有不能直接使用new对接口行实例化。

C#是单继承,接口是解决C#里面类可以同时继承多个基类地问题。

五.一.二接口地使用接口地声明在C#,声明接口使用interface关键字,一般形式如下:[访问修饰符] interface 接口名[ : 基接口列表]{//接口成员}说明:接口成员可以是属,方法,索引器与,不能包含字段,构造函数等。

所有接口成员隐式地具有了public访问修饰符,因此,接口成员不能添加任何访问修饰符。

接口主要用来定义一个规则,让企业内部或行业内部地软件开发员按标准去实现应用程序地功能。

因此,继承接口地类或结构需要实现接口地所有属,方法,索引器与,继承接口地方法与继承类相似 接口地继承接口也可以继承其它接口,而接口可以多继承,即接口可以从多个接口继承,基接口名之间用逗号分隔。

委托和事件的区别

委托和事件的区别

委托和事件的区别(讲的很详细)--转委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。

它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。

本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。

将方法作为方法的参数我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语:public void GreetPeople(string name) {// 做某些额外的事情,比如初始化之类,此处略EnglishGreeting(name);}public void EnglishGreeting(string name) {Console.WriteLine("Morning, " + name);}暂且不管这两个方法有没有什么实际意义。

GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。

现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法:public void ChineseGreeting(string name){Console.WriteLine("早上好, " + name);}这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据:public enum Language{English, Chinese}public void GreetPeople(string name, Language lang){//做某些额外的事情,比如初始化之类,此处略swith(lang){case Language.English:EnglishGreeting(name);break;case Language.Chinese:ChineseGreeting(name);break;}}OK,尽管这样解决了问题,但我不说大家也很容易想到,这个解决方案的可扩展性很差,如果日后我们需要再添加韩文版、日文版,就不得不反复修改枚举和GreetPeople()方法,以适应新的需求。

委托、事件和回调函数这3者之间到底是什么关系

委托、事件和回调函数这3者之间到底是什么关系

委托、事件和回调函数这3者之间到底是什么关系
简⽽⾔之,回调函数就是⼀个通过函数指针调⽤的函数。

如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤为调⽤它所指向的函数时,我们就说这是回调函数。

为什么要使⽤回调函数?
因为可以把调⽤者与被调⽤者分开。

调⽤者不关⼼谁是被调⽤者,所有它需知道的,只是存在⼀个具有某种特定原型、某些限制条件(如返回值为int)的被调⽤函数。

回调函数:就是指向指针的指针,保存的就⼀个地址,通常⽤在钩⼦过程,异步过程调⽤等等,因为是⼀个地址,不会携带任何其他的信息所以⼀般的回调函数不是类型安全的.
委托就⼀个类,他的每个实例就是对⼀个⽅法(定义好了返回值,输⼊参数类型,个数以及函数调⽤的约定)和其调⽤时操作的对象的⼀个封装. c#中的事件是依靠委托来实现的,事件就是⼀种通知机制,当⼀件事情发⽣时(⽐如说状态改变)通知给相关的其他对象.。

委托和事件的直接理解

委托和事件的直接理解

初学者在理解委托和事件时常常被msdn搞糊涂,为了让初学.net的人快速应用.net的委托和事件模型编程,我在这里主要是提出理解的关键,以下代码都可直接运行,先看下面的代码。

using System;namespace delegeteTest{class delegeteClass{public delegate void fHandler(int a); //关键-此行可以看成类的声明public fHandler f0;public void d(int a,int b ){int c=a+b;f0(c);}}class test{public void output(int mun){System.Console .WriteLine ("{0}",mun);}[STAThread]static void Main(string[] args){test t=new test ();delegeteClass dc=new delegeteClass ();dc.f0 =new delegeteTest.delegeteClass.fHandler (t.ou tput);//实例的初始化dc.d(2,3);}}}解释一下"关键": 实际上 public delegate void fHandler(int a);可以看成如下:class fHandler{.....}类内部由编译器自动完成,是一个sealed类通过反汇编可以看到,是一个类的声明,它检查加入自己的函数的信息,如,返回值和参数类型现在熟悉vc++的人可能感觉到public delegate void fHandler(int a);这句就象一个宏现在好了既然是个类的定义,那么也可以直接拿到命名空间下了using System;namespace delegeteTest{public delegate void fHandler(int a);//fHandler现在上升到了类的层次class delegeteClass{public fHandler f0;//声明了委托fHandler的实例f0;public fHandler f1;//也可以再声明一个fHandler类的实例f1;public void d(int a,int b ){int c=a+b;f0(c);}}class test{public void output(int mun){System.Console .WriteLine ("{0}",mun);}[STAThread]static void Main(string[] args){test t=new test ();delegeteClass dc=new delegeteClass ();dc.f0 =new delegeteTest.fHandler (t.output);//此行做相应的修改dc.d(2,3);}}}有以上可知public delegate void fHandler(int a)这行代码只能放在能够声明类的地方,自然fHandler.后面的函数都是静态方法了,如fHandler.Equals (...);那么fHandler到底声明了什么? 实际上是声明了函数的类型,既函数的有关信息(如返回值,参数类型)。

什么是委托?什么是事件?事件与委托的区别?

什么是委托?什么是事件?事件与委托的区别?

什么是委托?什么是事件?事件与委托的区别?什么是委托?委托是种:引⽤⽅法的对象。

此对象可以将指针指向引⽤的⽅法,也可以说对象(委托)将消息发给订阅者(⽅法)什么是事件?事件与委托的区别?事件是种:特殊的委托区别:事件是解决委托的两个缺陷1、不⼩⼼取消掉订阅者 (封装订阅)委托允许使⽤ +=和= 两种运算符,就会导致不⼩⼼取消掉订阅者,⽽事件不允许使⽤=2、包容类外也可以(发布)通知 (封装发布)事件确保只有包容类才能触发⼀个事件通知 [不允许类的外部执⾏事件通知] (事件只能在定义的类中调⽤(发布))换⾔之,事件提供了必要的封装来防⽌任何外部类发布⼀个事件或者取消之前的订阅者。

这样,就完美的解决了普通委托存在的两个问题PS: 参考《C#本质论》事件就是要解决下列代码中:+=和= ,在外部类中发布委托的问题public class Cooler{public Cooler(int temperature){this.Temperature = temperature;}public int Temperature { get; set; }public void OnTemperaTureChanged(int tem){if (tem > Temperature){Console.WriteLine($"Cooler On");}else{Console.WriteLine($"Cooler Off");}}}public class Heater{public Heater(int temperature){this.Temperature = temperature;}public int Temperature { get; set; }public void OnTemperaTureChanged(int tem){if (tem < Temperature){Console.WriteLine($"Heater On");}else{Console.WriteLine($"Heater Off");}}}class委托or事件{//声明委托// public delegate string delegateHandle(object sender, HandleEventArgs args);////声明事件//public event delegateHandle eventHandle;////已发事件的⽅法//public void Method(HandleEventArgs args)//{// if (eventHandle != null)// {// eventHandle(this, args);// }//}public delegate void delegateHandle(int tem);private delegateHandle _OndelegateHandleChanged;public delegateHandle OndelegateHandleChanged{get { return _OndelegateHandleChanged; }set { _OndelegateHandleChanged = value; }}private int temperature;public int Temperature{get { return temperature; }set { temperature = value; if(OndelegateHandleChanged!=null)OndelegateHandleChanged(value); } }}static void Main(string[] args){委托or事件 or = new委托or事件();Cooler cooler = new Cooler(80);Heater heater = new Heater(60);//or.eventHandle += Or_eventHandle;//or.Method(handler);or.OndelegateHandleChanged += cooler.OnTemperaTureChanged;or.OndelegateHandleChanged += heater.OnTemperaTureChanged;or.OndelegateHandleChanged = heater.OnTemperaTureChanged;or.OndelegateHandleChanged(45);Console.ReadLine();}View Code。

委托事件

委托事件

<五> 委托与事件1、委托C#的委托相当于C/C++中的函数指针,函数指针用指针获取一个函数的入口地址,实现对函数的操作。

委托是面向对象的,是引用类型,因此对委托的使用要先定义后实例化,最后才调用。

委托与C/C++有本质的区别:C/C++中的函数指针仅仅是一个内存地址,其中不包含任何有关函数的参数、返回值以及调用约定等方面的信息。

2、声明委托C#使用关键字delegate声明委托类型。

格式如下:[修饰符] delegate 结果类型委托名称([形式参数列表]);◆访问修饰符为可选项,可以使用new、public、private、protected和internal之一。

◆结果类型指委托对应方法的返回值的类型。

◆形式参数列表指定委托对应方法的参数。

注意,如果参数是一个指针,则必须用unsafe修饰符声明委托。

3、委托的实现在C#中,可以通过以下三个步骤定义和使用委托:声明、建立委托实例、实例化和调用。

上面已经介绍了如何声明一个委托,下面介绍后两个步骤,即建立委托实例、实例化和调用。

delegate语句定义委托的参数类型(形式参数列表的参数类型)和返回值类型(结果类型),任何具有匹配参数类型和返回值类型的方法均可用来建立此委托的实例。

因此,声明了一个委托后,为了实现这个委托,可以按如下的步骤操作:(1)建立委托实例:委托实例是委托所要调用的方法,它与声明的委托在以下三个方面必须相同。

◆方法类型。

如果委托被声明的为void(无返回值)结果类型,则委托实例(方法)必须是void类型;如果委托声明的是其它结果类型(如int类型),则委托实例(方法)返回值类型必须与之对应。

◆参数类型。

委托声明的参数列表类型必须与委托实例(方法)的参数列表类型相同。

◆参数个数。

委托声明的参数列表个数必须与委托实例(方法)的参数列表个数相同。

除上述三个方面外,其他方面,例如实例与委托的名称、参数名称不必相同。

只要这三个方面相同,就可以作为一个委托的实例过程。

第7章 委托与事件

第7章 委托与事件

7.2 事件
事件是对象发送的消息,以发信号通知操作的发生。操作 可能是由用户交互(如鼠标单击等)引起的,也有可能是 由某些其他的程序逻辑触发的。引发(触发)事件的对象 叫做事件发送方。捕获事件并对其做出响应的对象叫做事 件接收方。 在事件通讯中,事件发送方不知道哪个对象或方法将接收 到(处理)它引发的事件。所需要的是在源和接收方之间 存在一个媒介(或类似指针的机制),这一媒介就是代理 。
7.3.1 KeyPress事件
任务7.4 支撑知识
(三)KeyPress事件的局限 • KeyPress事件并不能识别出所有的按键事件,下列情况 是KeyPress不能识别的:
– 不能识别【Shift】、【Ctrl】、【Alt】键的特殊组合。 – 不能识别箭头(方向)键。注意:有些控件如命令按钮、 单选框、复选框不接受箭头键事件,但按下箭头会使焦点 移动到下一控件。 – 不能识别【PageUp】和【PageDown】键。 – 不能区分数字小键盘和主键盘的数字键。 – 不能识别与菜单命令无联系的功能键。
(五)引发事件 • 通过在Program类的Main方法中,调用heater对象的 boilwater方法
7.3 键盘事件
在Windows应用程序中,用户主要依靠鼠标和键盘下达命 令和输入各种数据,C#应用程序可以响应多种键盘及鼠标 事件。 利用键盘事件可以编程响应多种键盘操作,判断【Shift】 、【Ctrl】和【Alt】键的配合使用,也可以解释、处理 ASCII字符。 C#主要为用户提供了三种键盘事件:按下某ASCII字符键 时发生KeyPress事件;按下任意键时发生KeyDown事件; 释放键盘上的任意键时发生KeyUp事件。 只有获得焦点的对象才能够接受键盘事件。

委托与事件yts总结

委托与事件yts总结

委托与事件委托的应用:将方法作为另一个方法的参数view plaincopy to clipboardprint?1. using System;2. using System.Collections.Generic;3. using System.Text;4. namespace Delegate {5. //定义委托,它定义了可以代表的方法的类型6. public delegate void GreetingDelegate(string name);7. class Program {8. private static void EnglishGreeting(string name) {9. Console.WriteLine(”Morning, ” + name);10. } Www~11. private static void ChineseGreeting(string name) {12. Console.WriteLine(”早上好, ” + name);13. }14. //注意此方法,它接受一个GreetingDelegate类型的方法作为参数15. private static void GreetPeople(string name, GreetingDelegateMakeGreeting) {16. MakeGreeting(name);17. }18. static void Main(string[] args) {19. GreetPeople(”Jimmy Zhang”, EnglishGreeting);20. GreetPeople(”张子阳”, ChineseGreeting);21. Console.ReadKey();22. }23. }24. }1.委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

C#委托和事件从猫和老鼠的故事看事件

C#委托和事件从猫和老鼠的故事看事件

C#委托和事件从猫和老鼠的故事看事件1. 委托的含义:(MSDN)A delegate declaration defines a reference type that can be used to encapsulate a method with a specific signature.A delegate instance encapsulates a static or an instance method.Delegates are roughly similar to function pointers in C++;however,delegates are type-safe and secure.委托是一种引用方法的类型。

一旦为委托分配了方法,委托将与该方法具有完全相同的行为。

委托方法的使用可以像其他任何方法一样,具有参数和返回值。

我们可以这样理解委托:委托是函数的封装,它代表一“类”函数,它们都符合一定的签名:拥有相同的参数列表、返回值类型。

同时,委托也可以看成是对函数的抽象,是函数的类,此时的实例代表一个具体的函数。

2.事件的理解:C#使用委托模型来实现事件。

事件生成者类中不用定义事件的处理方法;事件订阅者是那些希望在事件发生时得到通知的对象,它们定义将和事件委托关联的事件处理方法。

当生成事件时,事件生成者通过调用事件委托“触发”事件,然后委托调用和它关联的事件处理方法。

3.猫和老鼠的例子首先,我们设定一个简单场景来说明,夜深人静,屋里有老鼠蹑手蹑脚的行动,且随时提防着猫,如果听到猫叫,老鼠闻声立即逃回洞里。

这个场景可以抽象为事件的几个要素:猫和老鼠是两个对象,猫是事件生成者对象,猫叫是一个方法,引发Cry事件;老鼠是事件订阅者对象,它提供事件处理程序Run()方法;通过委托和事件实现了老鼠对猫动静的监听,结果是老鼠听到猫叫就逃跑。

下面是完整的例子://定义一个委托,用来关联的Cry事件处理方法public delegate void CryEventHandler();//Cat类是事件的生成者,通过OnCry()方法引发Cry事件//但Cat类并不知道谁会监听Cry事件,以及如何理Cry事件,它只是告诉环境Cry事件发生了//通俗的解释是:猫叫了,但猫并不知道它的叫声对环境有什么影响public class Cat {//定义事件,表示猫叫public static event CryEventHandler Cry;public Cat() {Console.WriteLine("Cat:I'm coming.");}public virtual void OnCry() { Console.WriteLine("Cat:MiaoMiao");if (Cry != null) {Cry();}}}//Mouse类是事件的订阅者,定义了Cry事件发生时的处理方法Run()//通俗的解释是:老鼠在夜间行动时,时刻都在堤防着猫,如果听到猫叫声马上离开public class Mouse {public Mouse() {Cat.Cry += new CryEventHandler(Run);Console.WriteLine("Mouse:I go to find something,and I must always listen cat's crying.");}public void Run() {Console.WriteLine("Mouse:A cat is coming,I must go back!"); }}public class Demo1 {public static void Main(string[] args) {Mouse mouse = new Mouse();Cat cat = new Cat();cat.OnCry();Console.ReadLine();}}运行后控制台输出为:Cat:Mouse:I go to find something,and I must always listen cat's crying.I'm coming.Cat:MiaoMiao...Mouse:A cat is coming,I must go back!我们把猫和老鼠的场景设置复杂一点,假定有两种猫:一种是笨猫,它更本就追不上老鼠,所以老鼠即使听到它的叫声也不会逃走,对它描述为aBenCat;另一种猫就是能抓老鼠的猫了,让老鼠闻风丧胆,对它描述为smartCat。

委托和事件及函数指针的区别

委托和事件及函数指针的区别

委托和事件及函数指针的区别1.委托和事件的区别:⾸先最⼤的区别在于委托是⼀个类型,⽽事件最多只能算是⼀个委托类型的变量.事件作为委托类型的变量时,是私有的,但提供两个⽅法,⼀个是add⼀个remove⽤以追加和删除事件元素.在这私有访问修饰符和两个默认⽅法的基础上可以展现出事件与委托在安全层⾯上的区别,委托对象是公有的,在任何地⽅都可以被调⽤,因⽽难以避免被随意调⽤和冒名触发.且除了多播委托的追加和移除⽅法是⽤+=和-=,此外委托对象的赋值都是使⽤=号,这种赋值⽅法在追加⽅法时容易误操作⽽清空委托对象内原本的内容.⽽事件则不同,⾸先事件是在委托对象的基础上加了event关键字.加了event关键字之后,这个委托对象在编辑器⾥的图标已经从原本的蓝⾊格⼦变成了⼀道屎黄⾊的闪电,这⼀个改变是巨⼤的,就像成⼈礼⼀般.是标志着⼀个⼩对象从此长⼤成了事件.⽽改变之后的事件君已经完全与委托对象这种⼩正太不同了,再也不是任⼈调⽤,想改就改的了.因为事件君的私有特征,除了声明⾃⼰的类可以调⽤,此外任何地⽅都不能被调⽤,这就妥善的完爆了那些能调戏对象还想调戏事件君的外部类和外部⽅法.⽽事件君⼜留有⼀个形似属性中getset的与外部联系的出⼊⼝,即remove和add⽅法.⽤以移除和追加事件,但是任谁也不能像欺负委托对象那样,⽤⼀个=号就把原本的内容给替换了,因为事件君不认识啥是等号.此外事件君也不能⽤来给别的事件赋值,因为事件君说了,它只站在+=或-=的左边,⾄于右边嘛,呵呵,不如你去问问对象君?2.委托与函数指针的区别:委托具有⾯向对象的特征,⽽指针是⼀个⾯向过程的函数,指针只是表⽰⼀个地址或指向,⽽委托这个C#中的概念有着⾮常明确的层级结构.从object这个⾯向对象的根类开始往下追溯,Delegate类就是委托的超级⽗类,由于委托对象能接受多个⽅法,即多播委托的存在,因为在Delegate类下有⼀个叫做MulticastDelegate类在⽀持多播委托,这个类中,有两个字段,⼀个是_invocationCount⽤以记录个中元素的数量,⼀个是_invocationList,这个其实是object类型的数组,⽤以存储接收到的委托变量的值,且这个数组的原始⼤⼩及capacity的增长都是编译器⾃动完成.当然由于它是数组,那么想遍历个中元素也是可以的.遍历时通过⼀个强制类型转换,从object类转换成相应类型后还是可以逐个访问.⽽multicastDelegate是直接派⽣出⽤户⾃定义的委托类型的类.因⽽⽤户⾃定义的委托类型依然具备这些类成员,在⽤户⾃定义的委托类型中有个字段叫做_taget.给这个委托对象的赋值就是由这个字段接收并在上级类即MulticastDelegate类继承来的_invocationList集合中加上该值.这就是委托通过继承展现出来的层级结构,这是委托的⼀⼤特征.⽽指针君,是没有的.。

事件和委托的区别

事件和委托的区别

事件和委托的区别很多⼈说,事件即委托。

真的是这样吗?那么微软为何⼜要定义事件与委托两个概念呢?其实事件即委托,在我看来不如这样解释:事件是封装过的委托实例。

也就是说,事件是⾯向对象的产物,它是封装性⽐较典型的⽰例。

事件实际上是⼀个特殊的委托实例,不⽤事件也没有关系。

实际上事件只是削弱了委托的功能,event在编译器⾓度保护了你程序的安全,因为你只能使⽤+=、-=来注册事件了,⽽不能使⽤ = 为事件关联⽅法。

(在委托中还可以使⽤=来绑定⽅法,不过=是⼀种破坏性代码,不管之前是否已经绑定的有⽅法了,他都会将其清除)同⼀个⽅法你可以使⽤委托来调⽤,你也可以使⽤事件来调⽤。

那究竟有何不同?其实事件就是⼀个狭义的委托,也就是事件是⼀个⽤于事件驱动模型的专⽤委托.你可以在客户代码中直接调⽤委托来激发委托指向的函数,⽽事件不可以,事件的触发只能由服务代码⾃⼰触发。

也就是说在你的代码⾥委托你不但可以安排谁是它的调⽤函数,还可以直接调⽤它,⽽事件不能直接调⽤,只能通过某些操作触发。

除此之此,事件拥有委托的所有功能,包括多播特性。

即事件可以有多个事件处理函数,委托同样也可以是个多播委托.public class Heater{ private int temperature; public void BoilWater() { for (int i = 1; i <= 100; i++) { temperature = i; if (temperature > 95 && BoilEvent != null) { //执⾏委托,⽆需知道要执⾏哪些⽅法 BoilEvent(temperature); } } } public delegate void BoilHandle(int param); public event BoilHandle BoilEvent;//封装了委托}public class Alarm{ public void MakeAlert(int param) { Console.WriteLine("Alarm:⽔温已经超过{0}度.",param); }}public class Display{ public void ShowMsg(int param) { Console.WriteLine("Display:⽔已烧开,当前温度{0}度.", param); }}[TestClass]public class UnitTest1{ [TestMethod] public void TestMethod1() { Heater heater = new Heater(); Alarm alarm = new Alarm(); heater.BoilEvent += alarm.MakeAlert; heater.BoilEvent += new Display().ShowMsg; heater.BoilWater(); }}。

C#中委托和事件的区别实例解析

C#中委托和事件的区别实例解析

C#中委托和事件的区别实例解析本⽂实例分析了C#中委托和事件的区别,分享给⼤家供⼤家参考之⽤。

具体如下:⼤致来说,委托是⼀个类,该类内部维护着⼀个字段,指向⼀个⽅法。

事件可以被看作⼀个委托类型的变量,通过事件注册、取消多个委托或⽅法。

本篇分别通过委托和事件执⾏多个⽅法,从中体会两者的区别。

⼀、通过委托执⾏⽅法class Program{static void Main(string[] args){Example example = new Example();example.Go();Console.ReadKey();}}public class Example{public delegate void DoSth(string str);internal void Go(){//声明⼀个委托变量,并把已知⽅法作为其构造函数的参数DoSth d = new DoSth(Print);string str = "Hello,World";//通过委托的静态⽅法Invoke触发委托d.Invoke(str);}void Print(string str){Console.WriteLine(str);}}上述代码实现:①在CLR运⾏时,委托DoSth实际上就⼀个类,该类有⼀个参数类型为⽅法的构造函数,并且提供了⼀个Invoke实例⽅法,⽤来触发委托的执⾏。

②委托DoSth定义了⽅法的参数和返回类型③通过委托DoSth的构造函数,可以把符合定义的⽅法赋值给委托④调⽤委托的实例⽅法Invoke执⾏了⽅法但实际上让委托执⾏⽅法还有另外⼀种⽅式,那就是:委托变量(参数列表)public class Example{public delegate void DoSth(object sender, EventArgs e);internal void Go(){//声明⼀个委托变量,并把已知⽅法作为其构造函数的参数DoSth d = new DoSth(Print);object sender = 10;EventArgs e = new EventArgs();d(sender, e);}void Print(object sender, EventArgs e){Console.WriteLine(sender);}}上述代码实现:①委托DoSth的参数列表和⽅法Print的参数列表还是保持⼀致②委托DoSth中的参数object sender通常⽤来表⽰动作的发起者,EventArgs e⽤来表⽰动作所带的参数。

第5章 OOP基础(4)——属性和委托事件

第5章 OOP基础(4)——属性和委托事件
5
5.6 委托和事件
委托,顾名思义,就是中间代理人的意思. 通俗地说,委托是一个可以引用方法的对象,当创建一个委 托,也就创建一个引用方法的对象,进而就可以调用那个方 法,即委托可以调用它所指向的方法. 事件是建立在委托基础上的另一个重要特性.从本质上说, 事件就是当某个事情发生时,会自动去执行一些语句.事件 是特殊化的委托,委托是事件的基础.
理解多播
委托可以调用多个方法,称为多播,使用+和-运算实现方法的 增加和减少.如,在上例基础上添加如下代码: Call d= new Call(objMath.Divide); objCall += d; objCall(5,3); 则运行时,先调用objMath.Multiply(5,3); 则运行时,先调用 ; 再调用objMath.Divide(5,3); 再调用 ;
4
示例说明
学生类定义了一个私有字段nAge,也定义了公有属 学生类定义了一个 , 性Age,并包含 和set两个访问器,使其既可读也 两个访问器, ,并包含get和 两个访问器 可写. 可写. 在属性的 访问器中,用return来返回一个事物的 在属性的get访问器中 访问器中, 在属性的 来返回一个事物的 属性值. 属性值. 在属性的 访问器中可以使用一个特殊的隐含参数 在属性的set访问器中可以使用一个特殊的 在属性的 value.该参数包含用户指定的值,通常用在 访问 .该参数包含用户指定的值,通常用在set访问 器中,将用户指定的值赋值到一个类变量中. 器中,将用户指定的值赋值到一个类变量中. 如果没有 访问器,则表示属性是只读的;如果没 如果没有set访问器 如果没有 访问器,则表示属性是只读的; 访问器则表示属性是只写的. 有get访问器则表示属性是只写的. 访问器则表示属性是只写的

c委托与事件简单实例

c委托与事件简单实例

c委托与事件简单实例委托与事件是C#中常用的一种编程模式,它们可以让程序员更加灵活地控制程序的流程流转,使得程序的代码结构更加清晰,可读性更高。

在本文中,我们将以一个简单的例子来介绍委托与事件的使用方法,并探讨它们的一些重要特性。

假设我们正在开发一个游戏,这个游戏中有一个角色需要在不同场景下播放不同的动画。

我们可以使用一个委托来实现这个功能。

首先,我们需要声明一个委托类型,用来描述我们需要播放的动画:``` csharpdelegate void PlayAnimation(string animation);```这个委托类型表示一个接受一个字符串参数的方法,这个方法的返回值为 void,也就是没有返回值。

接着,我们可以定义一个包含这个委托类型为参数的方法:``` csharpvoid ChangeScene(PlayAnimation playAnimation){// 模拟切换场景的过程Console.WriteLine("正在切换场景……");// 播放动画playAnimation("idle");// 模拟切换场景完成的过程Console.WriteLine("场景切换完成!");}```这个方法接受一个 PlayAnimation 类型的参数 playAnimation,它的作用是在切换场景的过程中,播放一个名为 "idle" 的动画。

接下来,我们可以编写另外两个方法来实现这个委托:``` csharpvoid PlayIdle(string animation){Console.WriteLine("播放 " + animation + " 动画!");}void PlayWalk(string animation){Console.WriteLine("播放 " + animation + " 动画!");}```这两个方法是 PlayAnimation 类型的委托所需要的方法,它们接受一个字符串参数,用于指定播放的动画名称。

C#面向对象编程-委托和事件习题

C#面向对象编程-委托和事件习题
Console.write(i.ToString());
}
}
a)代码中存在错误,delegate void D(int i);不能定义在命名空间或者类之外
b)代码中存在错误,代码行V(new D(R));使用委托错误
c)程序正常运行,输出为0
d)程序正常运行,输出为210
C#面向对象编程-委托和事件
1.一个委托在某一时刻()指向多个方法。
a)可以
b)不可以
2.将事件通知其他对象的对象称为()
a)发布方
b)订户
c)通知方
3.以下的C#代码:
using System;
using System.Theading;
class App{
Public static voidMain()
b)代码正确编译和运行,并输出两次“将信寄往北大青鸟阿博泰克”;
c)代码将出现编译错误,
d)代码将编译正确,但运行时出现异常。
9>在C#中,假如有一个名为”MessageDelegate”的委托,下列能够正确定义
一个事件的是()
a)public delegate MessageDelegate messageEvent
Public class Carrier{
Public event SendMailDelegate sendEvent;
Static voidMain(){
Carrier t = new Carrier(); //1
t.sendEvent+= new SendMailDelegate(t_sendEvent);//2
b)public MessageDelegate messageEvent
c)private event MessageDelegate(messageEvent)

C#委托及事件

C#委托及事件

C#委托及事件在C#中,委托(delegate)是一种引用类型,在其他语言中,与委托最接近的是函数指针,但委托不仅存储对方法入口点的引用,还存储对用于调用方法的对象实例的引用。

简单的讲委托(delegate)是一种类型安全的函数指针,首先,看下面的示例程序,在C++中使用函数指针。

首先,存在两个方法:分别用于求两个数的最大值和最小值。

int Max(int x,int y){return x>y?x:y;}int Min(int x,int y){return x<Y?X:Y;< font>}上面两个函数的特点是:函数的返回值类型及参数列表都一样。

那么,我们可以使用函数指针来指代这两个函数,并且可以将具体的指代过程交给用户,这样,可以减少用户判断的次数。

下面我们可以建立一个函数指针,将指向任意一个方法,代码如下所示://定义一个函数指针,并声明该指针可以指向的函数的返回值为int类型,参数列表中包//括两个int类型的参数int (*p)(int,int);//让指针p指向Max函数p=max;//利用指针调用Maxc=(*p)(5,6);我们的问题在于,上面的代码中,为什么不直接使用Max函数,而是利用一个指针指向Max之后,再利用指针调用Max函数呢?实际上,使用指针的方便之处就在于,当前时刻可以让指针p指向Max,在后面的代码中,我们还可以利用指针p再指向Min函数,但是不论p指向的是谁,调用p时的形式都一样,这样可以很大程度上减少判断语句的使用,使代码的可读性增强!在C#中,我们可以使用委托(delegate)来实现函数指针的功能,也就是说,我们可以像使用函数指针一样,在运行时利用delegate动态指向具备相同签名的方法(所谓的方法签名,是指一个方法的返回值类型及其参数列表的类型)。

6.1 使用委托(delegate)6.1.1委托的建立建立委托(delegate),过程有点类似于建立一个函数指针。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

{
} class Program { public delegate Mammals HandlerMethod(); } }
HandlerMethod handler2 = SecondHandler;
public static Mammals FirstHandler()
{ return null; } public static Dogs SecondHandler() { return null; }
第1章 委托和事件
委托 事件 小结 实验
习题
事件Event
使用事件的好处 事件的工作方式 使用 Event 语句创建事件 EventHandler 委托的实现方法 自定义事件参数类 事件和委托的关系
使用事件的好处
.NET Framework 通常会在对象发生某些情况时自动 引发预构建的事件作为响应。
delegate void Del(int x);
Del d = delegate(int k) { System.Windows.Forms.MessageBox.Show(k.ToString()); };
协变:允许方法具有的派生返回类型比委托中定义的更多
class Mammals { } class Dogs : Mammals static void Main() { HandlerMethod handler1 = FirstHandler;
习题(续)
B.
[C#] public delegate control SortObjects(control objA, control objB); public object SortObjects(object objA, object objB);
C.
[C#] public delegate control SortObjects(object objA, object objB); public object SortObjects(control objA, control objB);
{
} public static void SecondHandler(Dog sheepDog) { } static void Main(string[] args) { HandlerMethod handler1 = FirstHandler; HandlerMethod handler2 = SecondHandler; } }
EventHandler 委托的实现
C#
要在 C# 中预订事件处理程序,可使用 Addition Assignment 运 算符(+=)将方法添加到分配给事件的 EventHandler 委托中。

血压
吃肉 :血压+5;
中风:事件
老婆: 处理该人的中风事件:掐人中 路人甲: 处理该人的中风:呼叫120
第1章 委托和事件
委托 事件 小结 实验
习题
小结
本章主要介绍了.NET Framework的委托和事件。 .NET Framework使用委托来实现事件驱动机制。 委托是一个方法列表,调用委托的效果等同于 调用此列表中所有的方法。事件可以看成是特 殊的委托实例。
第1章 委托和事件
委托 事件 小结 实验
使用委托的步骤 :
步骤1:声明委托。
步骤2:创建 类,创建委托调用的方法 。
步骤3:调用委托,进而调用指向的方法。
委托的广播
单路广播:一个委托,只指向一个方法 多路广播:一个委托,指向多个方法 累加 +=
减法 -=
注意:一般不使用返回值,如果有返回值, 以最后一个调用的方法为准 如果希望得到指向几个方法,使用 GetInvocationList 方 法
习题
实验
1.小猫会叫,老鼠听到会跑开,主 人听到会醒过来 2.狗也会叫,小偷听到就逃走,主 人听到就起来查看是否失窃
第1章 委托和事件
委托 事件 小Βιβλιοθήκη 实验习题习题1. 你最近已阅读了有关在面向对象的编程中使 用委托的资料,经理要求你对其他编程人员 作个讲解。因此要创建一个有关委托的优点 列表以说服其他编程人员使用委托,那么你 打算向列表中添加使用委托的哪些优点? 请选择所有符合条件的答案。 A.委托允许将方法作为参数传递给其他方法 B.委托有助于更改方法的签名
委托:方法的指针,通过调用委托,就能调用方法(一到多 个) 定义的语法 创建委托:构造函数 调用(有返回,和无返回) 广播:语法:+=,-=
使用委托VS抽象类,接口区别
Delegate类的成员
Delegate类的成员
成员 Method 属性 描述 返回委托引用的方法的只读属性。如果委托引用了多个方法,则 Method 属性将返回委托的调用列表中的最后一个方法。 返回包含委托引用的方法的对象的只读属性。如果方法是静态的,则 返回的值为 null。如果委托引用了多个方法,则 Target 属性将返回包 含调用列表中最后一个方法的对象。
请选择所有符合条件的答案。 A.Control B.Object
C.EventArgs
D. Sender
习题
4. 若要通过使用 EventArgs 类将数据从事件发布 者发送到事件的预订者,你将如何操作? 请选择一个最佳答案。
A.创建一个继承自 System.EventArgs 的自定义 EventArgs 类,并将新类作为自定义 EventHandler 委托声明的第二个参数的类型包 含在声明中
C.委托有助于一次调用多个方法
D.委托有助于在异步编程中指定回调
习题(续)
2. 你正在创建允许用户构建自定义图形用户界面 (GUI)的程序。你必须能对派生自 Control 类的 各类自定义控件的实例进行排序。Control 类继 承于 System.Object 类。以下哪个委托和方法签 名正确使用了协变和逆变? 请选择一个最佳答案。 A. [C#] public delegate object SortObjects(object objA, object objB); public control SortObjects(control objA, control objB);
A.C# 中使用 -=
B.C# 中使用 +=
员工都在监听老板的发彪事件,以做出相应的处理 事件参数:发彪事件(倒霉的人,时间) 事件发起人:老板 能处理事件的人:在职员工 员工离职后,不再监听事件
第1章 委托和事件
目标
本章学习目标: 使用 Delegate 类控制组件间的交互
使用 Event 语句、EventHandler委托和EventArgs 类控制组件间的交互
第1章 委托和事件
委托 事件 小结 实验
习题
委托:多态(方法的多态)
委托是引用类型,这与类和接口相似 。
间接调用方法
使用 Delegate 类间接调用方法
Target 属性
Combine 方法
将委托数组的调用列表串连在一起的静态方法。可使用该方法将多个 委托的调用列表组合到一个委托中。
CreateDelegate 方法
可用来创建引用实例或静态(中为共享)方法的委托的静态方 法。
Delegate类的成员 (续)
续表:
DynamicInvoke 方法 该方法调用委托的调用列表中的方法。被调用的方法的参数以数 组的形式传递。如果委托不使用参数,则参数数组应为 Null。 该方法返回一个单路广播委托数组,表示当前委托的调用列表。 如果委托只引用一个方法,则该数组将仅包含一个引用其自身的 元素。如果委托为多路广播,则该数组包含多个元素。 将指定委托的调用列表的最后一个实例从另一个委托中移除的静 态方法。 将指定委托的调用列表的所有实例从另一个委托中移除的静态方 法。
逆变:允许方法具有的派生参数类型比委托类型中的更少
class Mammal { } class Dog : Mammal { } class Program { public delegate void HandlerMethod(Dog sampleDog); public static void FirstHandler(Mammal elephant)
GetInvocationList 方法
Remove 方法
RemoveAll 方法
增强委托行为
使用新的 C# 2.0技术增强委托行为
C# 2.0 对委托的语言进行了某些增强,引入了匿名方法、协 变和逆变。
匿名方法 * 协变 逆变
匿名方法
能够省略参数列表,意味着可以将匿名方法转换为带 有各种签名的委托。
习题(续)
D. [C#] public delegate object SortObjects(control objA, _ control objB); public control SortObjects(object objA, object objB);
习题
3. EventHandler 类的预定义对象使用两 个标准参数。以下哪些选项表示这些 参数的类型?
要将代码块传递为委托参数,创建匿名方法则是唯一 的方法。
通过使用匿名方法,由于不必创建单独的方法,因此 减少了实例化委托所需的编码系统开销。
button1.Click += delegate(System.Object o, System.EventArgs e)
{ System.Windows.Forms.MessageBox.Show("Click!"); };
当用户在 UI 中单击自定义控件时,该控件就会触 发 Click 事件。
事件的工作方式
在程序中创建并使用自定义事件包含三个步骤 :
首先,必须在类中声明事件并确定将要使用的委托和参数 。 其次,必须定义在触发事件时要调用的委托。 最后,必须设计事件参数类,该参数类的实例会将信息传递给 被调用的方法。
相关文档
最新文档