委托和事件
委托和事件的区别

委托和事件的区别委托的本质,是⼀个类,⽽事件,是⼀个委托类型的私有变量加上两个公有⽅法(事件的+=和-=),这是本质区别。
打个⽐⽅,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)之间的介绍委托(delegate) 与事件(event)前言在之前的文章里介绍了C#中的委托(delegate)(Action、Func、Predicate)的基本含义及用法那本篇文章在这里还要介绍一个跟委托有很大关系的小伙伴——C#中的事件(event)事件跟委托是有很大联系的,所以也就导致很容易分不清他们两个,以及什么时候用这两个上面有博客提到委托,想单独了解委托的可以去看一下,本篇文章主要说一下什么是事件以及事件与委托的区别委托和事件的定义委托在这里再说一遍委托跟事件的简单定义(没有搜到特别准确的,都是大概定义,理解万岁)委托:delegate 是一种可用于封装命名或匿名方法的引用类型。
委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。
委托是一种动态调用方法的类型,属于引用型。
委托是对方法的抽象和封装。
委托对象实质上代表了方法的引用(即内存地址)委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以把多个方法链接在一起。
这样,在事件触发时可同时启动多个事件处理程序。
委托签名不需要与方法精确匹配。
事件事件:事件是特殊类型的多路广播委托,仅可从声明它们的类或结构(发行者类)中调用。
如果其他类或结构订阅了该事件,则当发行者类引发该事件时,会调用其事件处理程序方法。
事件表示C#中已定义的一个对象,即处理通知过程的对象通常,每个事件的发生都会产生发送方和接收方。
在.net框架中,事件是将事件发送者(触发事件的对象)与事件接受者(处理事件的方法)相关联的一种代理类,即事件机制是通过代理类来实现的。
当一个事件被触发时,由该事件的代理来通知(调用)处理该事件的相应方法委托和事件的区别简单说了一下两者的定义,眼神好的小伙伴这时候就会发现,事件的说明里有提到一句话:“事件也可以算一种特殊的委托”,这句话不是特别准确,但是也不妨可以这样理解。
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者之间到底是什么关系
简⽽⾔之,回调函数就是⼀个通过函数指针调⽤的函数。
如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤为调⽤它所指向的函数时,我们就说这是回调函数。
为什么要使⽤回调函数?
因为可以把调⽤者与被调⽤者分开。
调⽤者不关⼼谁是被调⽤者,所有它需知道的,只是存在⼀个具有某种特定原型、某些限制条件(如返回值为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类型),则委托实例(方法)返回值类型必须与之对应。
◆参数类型。
委托声明的参数列表类型必须与委托实例(方法)的参数列表类型相同。
◆参数个数。
委托声明的参数列表个数必须与委托实例(方法)的参数列表个数相同。
除上述三个方面外,其他方面,例如实例与委托的名称、参数名称不必相同。
只要这三个方面相同,就可以作为一个委托的实例过程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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 事件。
事件的工作方式
在程序中创建并使用自定义事件包含三个步骤 :
首先,必须在类中声明事件并确定将要使用的委托和参数 。 其次,必须定义在触发事件时要调用的委托。 最后,必须设计事件参数类,该参数类的实例会将信息传递给 被调用的方法。