唯一看明白额委托与事件讲解

合集下载

委托和事件

委托和事件

联系方式shuofeng87@第九章委托和事件9.1委托回调函数是一种非常强大的编程特性,包括窗口过程、异步过程调用都是需要回调函数的。

在C、C++和Pasal中,回调函数是通过函数指针实现的,但是,函数指针只是一个内存地址,这个地址不带任何额外信息,比如函数期望收到的参数个数、参数类型、函数的返回值类型以及函数的调用约定,所以函数指针是非类型安全的。

因此,Java中为了保证程序的安全性,不提供任何具有指针函数功能的结构。

但是C#中提供这种结构,这就是类型安全的委托。

9.1.1委托的定义委托是由Delegate类派生的子类的实例,它可以封装引用的方法,使被引用的方法可以像数据一样作为参数被进行传递和回调。

图9_1_1类试图委托定义的语法形式例:要引用的方法如下public static void DelegateMethod(string message){System.Console.WriteLine(message);}第一步,确定将要引用方法的签名,声明一个委托类型例:public delegate void Del (string message);[访问修饰符] delegate 返回值类型委托类名(形参列表);注意:1形式:委托声明类似于方法的定义,但是没有方法体,在返回值类型前要加上delegate 关键字2委托的签名:就是委托声明中的返回值类型,形参类型和形参个数要与被引用的方法匹配。

(不必完全匹配,委托支持协变与逆变,后面将详细讲解)3 委托的声明其实就是一个类的定义,所以可以在定义类的任何地方定义委托。

第二步,实例化一个委托例:Del handler = DelegateMethod;委托类名委托名= 被引用的方法名;注意:1这里只能是被引用的方法名,不可以带(),因为handler的本质是一个对象,对其进行赋值只是将DelegateMethod的内存单元地址传入handler中。

委托和事件的区别

委托和事件的区别

委托和事件的区别(讲的很详细)--转委托和事件在 .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()方法,以适应新的需求。

委托和事件的区别

委托和事件的区别

委托和事件的区别(讲的很详细)--转委托和事件在 .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()方法,以适应新的需求。

委托&事件

委托&事件

一、委托的定义:《高级汉语大词典》中是如下解释的:托付给别的人或机构办理。

要说生活中的意思其实大家都能理解,无非是“当某人(机构)需要完成一件自己不能或不应该完成的事情的时候,此人(机构)物色一个合适的且有能力完成此事的人选,然后提供必要的信息,将此事委托给物色到的人(机构)来完成。

” C#中的委托是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为,委托方法的使用可以像其他任何方法一样具有参数和返回值。

委托对象能被传递给调用该方法引用的代码而无须知道哪个方法将在编译时被调用。

委托是函数的封装,它代表一“类”函数。

他们都符合一定的签名:拥有相同的参数列表、返回值类型。

同时委托也可以看作是对函数的抽象,是函数的“类”。

此时,委托实例代表一个具体的函数。

委托应该和类同属一个层面,使用起来也很象一个类。

我们先来看一个委托使用的实例:public delegate void PrintHandler(string str); // 声明委托类型public class PrintStr{public void CallPrint(string input){Console.WriteLine(input);}}static void Main(string[] args){PrintStr myPrinter = new PrintStr();PrintHandler myHandler = null;// 将委托链接到方法,来实例化委托myHandler += new PrintHandler(myPrinter.CallPrint);if (myHandler != null)myHandler("Hello World!"); // 调用委托,相当于匿名调用委托所链接的方法myHandler -= new PrintHandler(myPrinter.CallPrint);if (myHandler == null)Console.WriteLine("myHandler==null");Console.Read();}得到的结果为Hello World!myHandler==null二、委托的特点1、一个委托对象可以搭载多个方法。

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⽤来表⽰动作所带的参数。

C#事件与委托详解【精华多看看】

C#事件与委托详解【精华多看看】

C#事件与委托详解【精华多看看】Delegatedelegate是C#中的⼀种类型,它实际上是⼀个能够持有对某个⽅法的引⽤的类。

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

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

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

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

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

在引⽤⾮静态成员函数时,delegate不但保存了对此函数⼊⼝指针的引⽤,⽽且还保存了调⽤此函数的类实例的引⽤。

其次,与函数指针相⽐,delegate是⾯向对象、类型安全、可靠的受控(managed)对象。

也就是说,runtime能够保证delegate指向⼀个有效的⽅法,你⽆须担⼼delegate会指向⽆效地址或者越界地址。

实现⼀个delegate是很简单的,通过以下3个步骤即可实现⼀个delegate:1.声明⼀个delegate对象,它应当与你想要传递的⽅法具有相同的参数和返回值类型。

2.创建delegate对象,并"将你想要传递的函数作为参数传⼊"。

3.在要实现异步调⽤的地⽅,通过上⼀步创建的对象来调⽤⽅法。

using System;public class MyDelegateTest{// 步骤1,声明delegate对象public delegate void MyDelegate(string name);// 这是我们欲传递的⽅法,它与MyDelegate具有相同的参数和返回值类型public static void MyDelegateFunc(string name){Console.WriteLine("Hello, ", name);}public static void Main(){// 步骤2,创建delegate对象(实例??)MyDelegate md = new MyDelegate(MyDelegateTest.MyDelegateFunc);// 步骤3,调⽤delegatemd("sam1111");}}输出结果是:Hello, sam1111了解了delegate,下⾯我们来看看,在C#中对事件是如何处理的。

委托和事PPT课件

委托和事PPT课件

......
void Mul{int x,
7
int y)
郑宇军 人民邮电出版社 2009
7
委托和方法
委托封装方法
DualFunction fun1 = new DualFunction(Add); fun1(2,3); fun1 = new DualFunction(Sub);
fun
void Add{int x,
10
委托和方法
传递委托对象
▪ 作为方法参数 ▪ 作为方法返回值
11
郑宇军 人民邮电出版社 2009
11
委托和方法
Delegate类型
▪ DynamicInvoke
Fun1(2.5,2)
Fun1.DynamicIn voke(2.5,2)
▪ Combine/Remove
DualFunction fun3 = fun1 + fun2
DualFunction fun1 = delegate(int x, int y) {
Console.WriteLine("{0}+{1}={2}", x, y, x+y); }
13
郑宇军 人民邮电出版社 2009
13
匿名方法
外部变量
捕获外部变量 捕获外部变量
double a=2.5, b=2; DualFunction fun1 = delegate(int a, int b) {
a++; b++; } fun1(a,b); DualFunction fun2 = delegate(int a, int b) {
a++; b--; } fun2(a,b);

委托和事件——精选推荐

委托和事件——精选推荐

委托和事件⼀、委托1、什么是委托委托是⾯向对象的、类型安全的,是引⽤类型。

使⽤delegate关键字进⾏定义。

委托的本质就是⼀个类,继承⾃System.MulticastDelegate,⽽它⼜派⽣⾃System.Delegate。

⾥⾯内置了⼏个⽅法,可以在类的外⾯声明委托,也可以在类的内部声明委托。

对委托的使⽤:先定义,后声明和实例化委托,然后作为参数传递给⽅法。

1.1 定义委托下⾯是⼏种委托定义的例⼦:1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;67namespace MyDelegateDemo8 {9// 也可以在类的外⾯定义委托10public delegate void NoReturnNoParaOutClass();1112public class MyDelegate13 {14// 声明⽆参数⽆返回值的泛型委托15public delegate void NoReturnNoPara<T>(T t);16// 声明⽆参数⽆返回值的委托17public delegate void NoReturnNoPara();18// 声明有参数⽆返回值的委托19public delegate void NoReturnWithPara(int x, int y);20// 声明⽆参数有返回值的委托21public delegate int WithReturnNoPara();22// 声明有参数有返回值的委托23public delegate string WithReturnWithPara(out int x,ref int y);24 }25 }1.2 声明并实例化委托实例化委托时参数传递的是⼀个⽅法,⽅法的签名必须和委托的签名⼀样(即⽅法的返回值类型、参数列表的参数类型都必须和定义的委托⼀致)。

一篇文章彻底搞清楚c#中的委托与事件

一篇文章彻底搞清楚c#中的委托与事件

⼀篇⽂章彻底搞清楚c#中的委托与事件⼀、什么是委托呢?听着名字挺抽象,确实不好理解。

⾯试官最喜欢考察这个,⽽且更喜欢问:“委托和事件有何异同?”。

如果对⼀些知识点没有想明⽩,那么很容易被绕进去。

研究任何事物,我们不妨从它的定义开始,委托也不例外。

那么先来看c#中的委托定义,先来个例⼦:public delegate void GetPacage(string code);这个委托,看起来就是个⽅法签名,取包裹,需要验证码。

与⽅法签名不同的地⽅,在于多了⼀个delegate。

c#中不乏⼀些便利好⽤的语法,⽐如foreach、yield,每⼀个关键字背后都有⼀段故事。

delegate的背后,⼜有什么故事呢?其实就是c#编译器帮我们做了些什么事情。

要知道这个,我们得看⽣成的IL,如何查看IL?请看下图:vs命令⾏中输⼊ ildasm,会打开⼀个反编译的窗⼝,选择我们的程序集,如下图:从图中可以看出:1、委托的本质就是⼀个密封类,这个类继承了MulticastDelegate(多播委托)2、委托的构造函数,有两个参数,⼀个类型是IntPtr,⽤来接收⽅法的,如下图:3、可以同步调⽤(Invoke),也可以异步调⽤(BeginInvoke、EndInvoke)注:1、多播委托:⼀个委托可以代表多个相同签名的⽅法,当委托被调⽤时,这些⽅法会依次执⾏2、IntPtr表⽰窗⼝的时候,叫它“句柄”,表⽰⽅法时,叫它“指针”3、异步调⽤:会产⽣⼀个线程,异步执⾏⼆、委托有什么⽤?在js中,并没有提委托的概念,却有“回调”,⽐如ajax回调。

把⼀个函数传递到另外⼀个函数⾥执⾏,是⾮常⾃然的事情。

但是在c#中,不能直接把⽅法名传递进去。

所以创造了委托这么个类型。

c#中的委托也是为了回调。

委托有什么好处?举个例⼦:皇帝颁发圣旨,得派⼀个⼤⾂去。

⼤⾂到了⽬的地,宣读圣旨后,这才得以执⾏。

这说明以下两点:1、委托有很好的封装性2、委托的实例化与它的执⾏是在不同的对象中完成的三、委托与代理我说的代理,是指设计模式中的代理。

我眼中的事件委托

我眼中的事件委托

我眼中的事件委托上⼀篇博⽂写了,总想知道委托的使⽤场景。

⽹上查出事件委托、回调函数等。

今天我也写写对事件委托的认知,常思考并总结,对⾃⼰总是有好处的,能让知识更加系统完善。

⼈⽆完⼈,虽然我也很怕引来⼤家的⼀堆谩骂声,但是我也想招来⼀群志同道合的友⼈。

就像三国的曹操,有⼈谩骂,有⼈赞扬,有⼈⽰之为敌⼈,有⼈⽰之为我主。

好拉,不写点费话,总觉得缺少什么。

下⾯谈谈事件委托,这是⼀对词组,拆分为事件(关键字event)、委托(关键字delegate)⽹上看⼀位总结委托与事件的作⽤,⽽且对于事件委托的阐述也很棒。

委托的作⽤:占位,在不知道将来要执⾏的⽅法的具体代码时,可以先⽤⼀个委托变量来代替⽅法调⽤(委托的返回值,参数列表要确定)。

在实际调⽤之前,需要为委托赋值,否则为null。

事件的作⽤:事件的作⽤与委托变量⼀样,只是功能上⽐委托变量有更多的限制。

(⽐如:1.只能通过+=或-=来绑定⽅法(事件处理程序)2.只能在类内部调⽤(触发)事件。

)委托的声明使⽤,上⼀篇也讲了⼀部分内容,可以参照了解。

现在我们来看看中按钮的事件⽅法:protected void btnClose_OnClick(object sender, EventArgs e)=》⽅法:btnClose_OnClick(⽅法名如果按规定来命名的话,其实可以看出是⼀个按钮的Click点击事件)=》参数:(1)sender:即触发事件的主体,事件的主体可以多样化,故被定义成object类型,通过它能区分不同事件的主体。

多事件的回调函数就是通过它来区分 (2)e:即事件参数,当事件发⽣时,可以通过该参数来传递⼀些数据。

如果你需要⾃定义它,可通过继承 EventArgs类来实现完整的的例⼦如下,这个例⼦主要是说明了btnOpen注册了btnClose的事件,即点击btnOpen按钮会实现btnOpen+btnClose事件。

aspx页⾯代码:<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="DelegeEventTest.WebForm1" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head runat="server"><title></title></head><body><form id="form1" runat="server"><div><asp:Button ID="btnOpen" Text="⾃动化开关灯" runat="Server" OnClick="btnOpen_OnClick" /><asp:Button ID="btnReset" Text="重置" runat="server" OnClick="btnReset_Onclick" /><asp:Button ID="btnClose" Text="关灯" runat="Server" OnClick="btnClose_OnClick" /><br /><br /><br /><asp:Label ID="lblShow" runat="server" /></div></form></body></html>cs代码:using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;namespace DelegeEventTest{public delegate void EventHandler1(object sender, EventArgs e);public partial class WebForm1 : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){this.btnOpen.Click += new EventHandler(btnClose_OnClick);}protected void btnOpen_OnClick(object sender, EventArgs e){this.lblShow.Text = "灯已经开启!";this.lblShow.Text += "<br/>";this.lblShow.Text += "过了⼀分钟后";this.lblShow.Text += "<br/>";}protected void btnClose_OnClick(object sender, EventArgs e){this.lblShow.Text = "灯已经关闭!";}protected void btnReset_Onclick(object sender, EventArgs e){this.lblShow.Text = string.Empty;}}}上⾯的例⼦⼤家好像连个delegate的关键字都没有看到,其实是因为微软已经封装好了,其位于命名空间System下⾯。

第11章委托与事件

第11章委托与事件
课外
课外习题请参见PPT。
布置作业
1.完成书后习题1~3
了解一些常用的系统预定义好的方法
教学内容和方法
教学提示
委托作为C#的一个重要知识点,在本节进行了单独的讲述。但是委托依然是一个不太好理解的知识。教师需要结合函数指针和生活中的一些形象化的例子来说明委托的作用。至于委托的使用本身倒是没什么难处。
最后本章介绍了一些常用的方法。掌握这些方法对于以后的编程具有很大的帮助。教师在讲解此处的时候需要尽量多结合与事件的概念,定义及使用。
教学目标
1.理解委托的含义。
2.会正确定义和使用委托
3.理解委托与事件的关系
4.掌握使用事件。
5.了解事件的编写。
教学重点
1.事件的概念与使用
教学难点
1.对委托的理解
建议学时数
课堂教学(4课时)
11.1
教学提示:
本部分主要达到以下目的:
理解并掌握委托的使用

事件和委托——精选推荐

事件和委托——精选推荐

事件和委托事件与委托前⾔事件与委托在很多⾯试,或者提问的场合⼈都是问事件委托有什么区别,其实事件和委托本质是没有区别的,事件的内部是由委托来实现的,事件是⼀个对象,委托是类型。

在没有严格的定义下也可以说成事件的是⼀种特殊的委托(其实这不是微软官⽅的定义,只是我对各个⾯试⼈员的总结,当我说事件不是委托时他们都狂殴我),其实委托和事件这两个概念是完全配合的。

委托⼀般都是先从委托讲到事件:委托是函数的指针,他能够引⽤函数,通过传递地址的机制来完成。

委托是⼀个可带参数也可不带参数的类,当你要对该类实例化时需要指定该类的的构造函数,该构造函数返回值的类型和参数类型、个数必须定义的委托⼀致。

例如:Class person{Delegate string Speak(string hello);Public static void Main(string[] args){Speak spk=new Speak(SpeakEnglish);String myspk= spk(hi);Console.WriteLine(myspk);}Public string SpeakEnglish(string hi){Return “English:”+hi;}}在此实例中spk引⽤的函数SpeakEnglish,就相当于指针指向了SpeakEnglish事件事件其实⼤家都接触过,只是很多时候都是知其然,不知其所以然。

我们在做winform,和webform时候点击button时后台会产⽣⼀个click,其实这就是⼀个button点击事件。

让我们通过⼀个例⼦来学习,假定有这样的情节:现在有⼀个Counter的类,它有⼀个⽅法 CountTo(int countTo, int reachableNum),该⽅法表⽰:在指定的时间段内(0~~countTo),当到达指定的时间点reachableNum时,就触发⼀次NumberReached事件。

C#委托和事件详解

C#委托和事件详解

前言:在我们学习C#的过程中,我们会学习到C#委托和事件,由于这是C#中比较高级的内容,所以学起来相当的费力,没有一定的时间是体验不来的,正好我这几天在学这个知识点,所以做一个小总结,希望和我一样的童鞋们能够参考一下,我们共同进步!,此博客属于学习笔记,写的不好,还请见谅!1. 委托的定义(1) 将方法作为变量使用的一种机制,就是将方法当作变量用(声明,赋值,传参)(2) 将变量当作方法来用,首先就要去声明变量,就要考虑变量的类型,就是(委托变量,对应方法的返回值,参数等),顾名思义:委托就是委托别人去干某些事情,下面是一个实例方法的实现例如:我现在饿了,但是我很懒,就是不想出去买,所以这时候我可以委托室友帮我带一份,这样我就已经实现委托了,如果我想去吃饭的话实现的代码是:class Program{static void Main(string[] args){chum ch = new chum();ch.EatFood();Console.ReadKey();}}class chum{public void EatFood()最后将这几点做个总结如下:(1)使用委托,就是需要有一个变量来指向这个方法(2)定义一个委托类型的变量,先要定义一个委托(这个委托规定了可以赋值方法的信息)(3)语法:delegate 方法返回类型委托类型名(方法可用参数)(4)委托就是一个类型(5)使用委托就是让方法可以当成变量用1) 弄清楚那些方法需要当作变量用2) 根据方法的返回值和类型定义委托类型3) 声明委托类型的变量4) 初始化委托变量(就是赋值)5) 此时这个委托变量就是等价于方法了,使用委托变量加圆括号就是在调用指定的那个方法6) 既然是变量,就可以通过参数传递等其他方式使用了2. 静态方法实现委托(1)委托变量在指向方法的时候,就是"相当于"存放着方法的地址,在调用的时候直接到内存中找到方法代码,执行(2) 既然委托只是存储方法,就不需要理会这个方法是什么类型的(静态还是实例的)(3)实现调用方法的时候就是直接为其赋值即可?C#中常见的字符串方法1.1 字符串大小写方法原型string <strName>.ToUpper(); //返回字符串转换的大写形式string <strName>.ToLower(); //返回字符串转换的小写形式例如:用户在输入用户名的时候,可能会大小写输入混乱,但是我们可以转换(全部转换为大写或者全部转化为小写)一下,使用户也能够登录成功Console.Write("请您输入用户名:");//全部转换为大写string username = Console.ReadLine();string usernameupper = username.ToUpper();//全部转换为小写string usernamelower = username.ToLower();Console.WriteLine("大写是:{0},小写是:{1}", usernameupper, usernamelower);1.2 移除首尾指定字符Trim 移除一组指定字符的首尾匹配项方法原型(1)string <strName>.Trim(); //移除首尾的空格string str = " 韩迎龙";string firstendnullstr = str.Trim();Console.WriteLine(firstendnullstr.Length); 输出信息:3(2)string <strName>.Trim(new char[]{'<char>'}); //移除首尾指定的字符(必须是首尾的字符)string str = "韩迎龙韩";string firstendnullstr = str.Trim(new char[] { '韩' });Console.WriteLine(firstendnullstr); 输出信息:迎龙TrimStart 移除一组指定字符的开头匹配项方法原型(1)string <strName>.TrimStart(); //移除开头的空格string str = " 韩迎龙";string firstendnullstr = str.TrimStart();Console.WriteLine(firstendnullstr.Length); 输出信息:4(2)string <strName>.TrimStart(new char[]{'<char>'}); //移除开头指定的字符 string str = "韩迎龙韩";string firstendnullstr = str.TrimStart(new char[] { '韩' });Console.WriteLine(firstendnullstr); 输出信息:迎龙韩TrimEnd 移除一组指定字符的结尾指定项方法原型(1)string <strName>.TrimEnd(); //移除结尾的空格string str = " 韩迎龙";string firstendnullstr = str.TrimEnd();Console.WriteLine(firstendnullstr.Length); 输出信息:4(2)string <strName>.TrimEnd(new char[]{'<char>'});string str = "韩迎龙韩";string firstendnullstr = str.TrimEnd(new char[] { '韩' });Console.WriteLine(firstendnullstr); 输出信息:韩迎龙1.3 字符串的比较Compare()方法方法原型(1) int Compare(String,String); //比较两个字符串对象int strCompare=pare("sFsFsF","Sfsfsf"); //输出信息:0(2) int Compare(string,String,Boolean) //比较两个字符串对象,是否忽略大小写 int int dou = pare("sdsSD", "sdsSd", true); //输出信息:0(3) int Compare(String,String,StringComparison) //参数指定比较是使用当前区域性还是固定区域性,是考虑还是忽略大小写,是使用字排序规则还是序号排序规则。

委托与事件——精选推荐

委托与事件——精选推荐

委托与事件⾸先给出⼀堆委托的介绍内容,不理解的话,也没有问题,等看了 Demo 再回过头来看就 OK 了:委托是⼀个类,它定义了⽅法的类型,使得可以将⽅法当做另⼀个⽅法的参数来进⾏传递,这种将⽅法动态地赋值给参数的做法,可以避免在程序中⼤量的使⽤判断语句,同时使得程序具有更好的扩展性。

委托是⼀个可以保存对⽅法的引⽤的类,委托类具有⼀个签名,并且它只能对与其签名匹配的⽅法进⾏引⽤,这样,委托就等效于⼀个类型安全函数指针或者是⼀个回调。

⼀个委托声明⾜以定义⼀个委托类,声明提供委托的签名,公共语⾔运⾏库提供实现。

委托呢,可以看做是对函数的⼀个封装,可以当做给⽅法的特征指定⼀个名称,委托具有如下特点:委托类似于 C++ 中的函数指针,但其实类型安全的,委托允许将⽅法作为参数进⾏传递,委托可以⽤于定义回调函数,委托可以链接在⼀起,例如,可以对⼀个事件调⽤多个⽅法,⽅法名不必与委托签名完全匹配。

下⾯的 Demo 将演⽰如何将委托看做⼀个类型,并且通过委托来实现将⽅法作为参数传递Delegate.DelegateType 类的代码如下using System;namespace Delegate{/// <summary>/// ⾸先必须要定义⼀个委托类型,在定义委托类型时/// 您可以有参数,同时你可以让这个委托返回⼀个值,⽐如 int 类型的值/// </summary>public delegate void DelegateDemo();public class DelegateType{private string name;/// <summary>/// 构造函数/// </summary>/// <param name="name"></param>public DelegateType(string name){ = name;}/// <summary>/// 此处定义⼀个⽅法,⽤来实现将这个⽅法传递给委托/// 然后通过委托类型来调⽤这个⽅法/// </summary>public void SayHello(){Console.WriteLine("Hello , " + name);}public void SayBye(){Console.WriteLine("Good Bye , " + name);}/// <summary>/// 这⾥就是成功的使⽤委托了/// 可以看到是以⼀个委托类型来作为参数传递/// 在这⾥,您完全可以把这个委托类型的参数 delegatePara 看做事⼀个⽅法/// 这样就是成功实现利⽤委托来传递⽅法参数了/// </summary>/// <param name="delegatePara"></param>public void Talk(DelegateDemo delegatePara){delegatePara();}}}然后就是 Main ⽅法中的代码如下using System;namespace DelegateTest{class Program{static void Main(string[] args){Delegate.DelegateType dele =new Delegate.DelegateType("XiaoZhen");//通过委托传递进⽅法 Talk 的参数是⼀个⽅法类型 SayHellodele.Talk(dele.SayHello);dele.Talk(dele.SayBye);Console.ReadKey();}}}下⾯就给出效果的截图了从上⾯的 Demo 可以看出,通过委托,我们已经成功实现了将⼀个⽅法作为另外⼀个⽅法的参数来进⾏传递。

委托和事件的总结(应用场景、扩展【匿名函数、lambda】)

委托和事件的总结(应用场景、扩展【匿名函数、lambda】)

委托和事件的总结(应⽤场景、扩展【匿名函数、lambda】) 不知道很多⼈在写东西给⼤家分享的时候是⾃⼰也不清楚,⼜或者是不愿意让⼤家明⽩,做事云⾥雾⾥的绕来绕去。

反正我经常看到不准确、看不明⽩的学习资料、博客、答案等。

后来我总结了下【缺少应⽤场景】。

下⾯今天我给⼤家说说我理解和平时⽤到的委托、事件,童鞋们看完觉得有帮助的来个评论。

⾸先咱们看⼀下委托怎么声明:private delegate void m_delegate();这句就声明了⼀个委托,看不懂没关系,咱们挨个词解释:1.private 作⽤域2、delegate 委托的关键字3、void 返回值类型4、m_delegate 我定义委托的名字5、() 说明我定义的委托没有参数,如果有参数可以是这样(string str)好了解释完委托的声明语法,看看下⾯⽐较常规的⽅法定义语法://⽅法1private void function1(){Console.WriteLine("1");}//⽅法2private void function2(){Console.WriteLine("2");}//⽅法3private void function3(){Console.WriteLine("3");}上⾯我定义了3个⽅法,⼤家看看这三个⽅法:1)私有的、2)没有返回值、3)没有传⼊参数、4)名字不⼀样。

除了名字不⼀样,他们有3个共同点。

不只是这3个⽅法有共同特点,它们跟咱们⼀开始声明的委托也是很象。

共同点也是:1)私有的、2)没有返回值、3)没有传⼊参数好了,⼤家看出点什么了没有,我说⼀下委托我⾃⼰的定义:将长的很像的⽅法(作⽤域、返回值、传⼊参数相同)抽象出来,然后起⼀个名字,就是委托。

简单点就是有共同特性⽅法的抽象。

那么,好像是知道了什么是委托,怎么⽤呢?看看下⾯代码的应⽤场景:int aa;private void MainFunctiuon(){aa=1;//逻辑判断switch (aa){case 1:function1();break;case 2:function2();break;case 3:function3();break;default:break;}}//调⽤上⾯的MainFunctiuon⽅法private void Test(){MainFunctiuon();}【执⾏Test()结果是执⾏function1⽅法的⽅法体的内容,——打印1】代码解释:我定义了⼀个int类型的变量aa,当然后判断aa的值来执⾏相应的函数,如果要是有很多种可能性咱们的代码就⽆限多了,怎么办呢?咱们试试委托://原始代码(跟上⾯的⼀致)int aa;private void MainFunctiuon(){aa = 1;switch (aa){case 1:function1();break;case 2:function2();break;case 3:function3();break;default:break;}}//利⽤委托的⽅法private void MainFunctiuon1(m_delegate Delegate){Delegate();}private void Test(){MainFunctiuon1(function1);}【执⾏Test()结果是执⾏function1()⽅法体的内容,——打印1】对⽐下MainFunctiuon1和MainFunctiuon这两个⽅法:private void MainFunctiuon(){aa = 1;switch (aa){case 1:function1();break;case 2:function2();break;case 3:function3();break;default:break;}}private void MainFunctiuon1(m_delegate Delegate){Delegate();}哪个简洁⼀⽬了然.在上⾯的例⼦中,委托的⽤法就是把委托当成类型来⽤了(⽅法的类型,⽅法名当成了参数)。

第7章 委托和事件

第7章 委托和事件

第7章委托和事件回调(callback)函数是Windows编程的一个重要部分。

如果您具备C或C++ 编程背景,应该就曾在许多Windows API中使用过回调。

Visual Basic添加了AddressOf关键字后,开发人员就可以利用以前一度受到限制的API了。

回调函数实际上是方法调用的指针,也称为函数指针,是一个非常强大的编程特性。

.NET以委托的形式实现了函数指针的概念。

它们的特殊之处是,与C函数指针不同,.NET委托是类型安全的。

这说明,C中的函数指针只不过是一个指向存储单元的指针,我们无法说出这个指针实际指向什么,像参数和返回类型等就更无从知晓了。

如本章所述,.NET把委托作为一种类型安全的操作。

本章后面将学习.NET如何将委托用作实现事件的方式。

本章的主要内容如下:●委托●匿名方法●l表达式●事件7.1 委托当要把方法传送给其他方法时,需要使用委托。

要了解它们的含义,可以看看下面的代码:int i = int.Parse("99");我们习惯于把数据作为参数传递给方法,如上面的例子所示。

所以,给方法传送另一个方法听起来有点奇怪。

而有时某个方法执行的操作并不是针对数据进行的,而是要对另一个方法进行操作,这就比较复杂了。

在编译时我们不知道第二个方法是什么,这个信息只能在运行时得到,所以需要把第二个方法作为参数传递给第一个方法,这听起来很令人迷惑,下面用几个示例来说明:●启动线程——在C# 中,可以告诉计算机并行运行某些新的执行序列。

这种序列就称为线程,在基类System.Threading.Thread的一个实例上使用方法Start(),就可以开始执行一个线程。

如果要告诉计算机开始一个新的执行序列,就必须说明要在哪里执行该序列。

必须为计算机提供开始执行的方法的细节,即Thread类的构造函数必须带有一个参数,该参数定义了要由线程调用的方法。

●通用库类——有许多库包含执行各种标准任务的代码。

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

一、在控制台下使用委托和事件
我们都知道,C#中有“接口”这个概念,所谓的“接口”就是定义一套标准,然后由实现类来具体实现其中的方法,所以说“接口,是一组类的抽象”。

同样道理,我们可以将“委托”理解为“方法的抽象”,也就是说定义一个方法的模板,至于这个方法具体是怎么样的,就由方法自己去实现。

我们知道接口的最大好处就是可以实现多态,同理,“委托”是可以实现方法的多态,当我们想调用某个具体方法的时候,我们不直接调用这个方法,而是去调用这个委托。

当然,我们必须在具体方法和委托之间建立某种关联。

下面我们来看例子。

首先,我们定义一个委托:
public delegate void SaySomething(string name);
这跟抽象方法的语法格式很相似,只是多了一个关键字delegate。

既然是对方法的一种抽象,那么我们最关注的当然就是方法的返回值以及方法的参数了。

所以上面红色的部分就是我们定义出来的一个规矩,如果某个方法想委托我去做事,那么请你遵循我的规矩,就是返回值为void,参数为一个字符串。

我们这个委托的含义是,当某个人来了,就向他说点东西。

好,既然我们已经定义了这个规矩,下面我们就定义具体的方法了。

public void SayHello(string name)
{
Console.WriteLine("Hello," + name + "!");
}
public void SayNiceToMeetYou(string name)
{
Console.WriteLine("Nice to meet you," + name + "!");
}
我们这里一共定义了两个方法,一个是向某人说Hello,另一个是向某人说Nice to meet you。

我们看到,这里定义的两个方法的返回值和参数跟我们前面定义的“委托”是一致的。

接下来,我们来看事件。

public event SaySomething come;
我们定义了一个事件,这个事件是“有人来了”,注意定义的时候我们使用event关键字,除此之外,我们还加上了前面定义的“委托”的名字。

这个意思是说,我这个事件只会跟“SaySomething”打交道,并且,当我这个事件发生的时候,我会通知关注我的这些“委托”(再由这些“委托”去调用具体的方法)。

我们来定义一个测试方法:
public void test() {
SaySomethingsayhello = new SaySomething(SayHello);
SaySomethingsaynice = new SaySomething(SayNiceToMeetYou);
come += sayhello;
come += saynice;
come("张三");
}
方法体中的前面两行是用来实例化委托,注意我们用到了new关键字,就好像实例化一个类一样,然后传入一个参数,但这个参数不是string类型、也不是int类型,而是一个方法名。

再下面两行就是将委托加到事件上,意思是说,如果你这个事件发生了,就告诉我一声。

可以通过“+=”来将n个委托实例加到某个事件上,一旦这个事件发生,所有的这些委托实例都会得到通知。

最后一行是触发一个事件,注意我们是直接用一个事件名,然后跟一个参数,这又跟“委托”中定义的那个规矩一致(即,要有一个string类型的参数)。

最后运行一下
static void Main(string[] args)
{
Program program = new Program();
program.test();
Console.Read();
}
我们回过头来再看一下“事件”的定义:
public event SaySomething come;
这里已经指出了“委托”的名字,所以,我们可以直接将方法加到事件上,而省略“委托”的实例化过程,因此上面的test()方法可以简单写为:
public void test() {
come += SayHello;
come += SayNiceToMeetYou;
come("张三");
}。

相关文档
最新文档