当前位置:首页 > Windows程序 > 正文

【温故知新】C#委托delegate

2021-05-25 Windows程序

在c#的学习过程中,学到委托与事件总会迷糊一段时间,迷糊过后自然而就似懂非懂了~,所以最近我打算把以前所学的迷糊过的知识总结,温故知新,总结记录下来。

首先,我们来看一下msdn对委托的定义:

delegate 关键字用于声明可用来封装命名方法的引用类型。委托大致类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。

delegate 可让您传递一个函数作为参数。委托的类型安全要求作为 delegate 传递的函数具有与 delegate 声明相同的签名。

委托是事件的基础。

我们都知道,c++中的函数是可以通过函数指针来当做参数使用的,c#中没有指针这种东西,怎么办?所以弄出一个delegate出来。

但与函数指针相比,delegate有许多函数指针不具备的优点。 首先,函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。

在引用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。 其次,与函数指针相比,delegate是面向对象、类型安全、可靠的受控(managed)对象。

也就是说,runtime能够保证delegate指向一个有效的方法,你无须担心delegate会指向无效地址或者越界地址。

接下来,我们看看c#代码如何声明、实例化、使用一个委托:

private delegate void MyDelegate(string msg); static void Notify(string name) {   Console.WriteLine("Notification received for: {0}", name); } MyDelegate mydelegate=new MyDelegate(Notify); mydelegate("yoyoyo!");

其中要注意的是:

1、委托不能被定义为static的。

2、返回类型,函数参数一定要和被委托函数一样(继承时)。

3、委托可以链接在一起;例如,可以对一个事件调用多个方法。通过+=,-=操作。

看到这里,我们大致知道“委托”是个什么东西了,但是,相信初学者还有一大堆疑问,委托具体到底是拿来干什么的呢???写程序的时候怎么用它才合适?这些问题也困扰了我许久。

从字面意思看“委托”:把事情托付给别人或别的机构办理,举日常生活中例子:

中午午餐时间,由于工作还没做完,所以叫同事帮带一份午餐,这是一种“委托”。

玩游戏升级太慢,哪有那么多时间升级,果断找人帮代练~又快又舒心~满级之后再把号给我,这也是一种“委托”。

总之,就是在你忙的时候叫其他人帮你做事,这让我们想到了什么?-----异步编程!,例如在做一些耗时操作时,在不影响主线程情况下异步,特别是UI线程,委托delegate在大多数情况下,就是用来在异步编程中充当“跑腿的”。

在这里我们就不讨论异步编程,也不涉及异步编程,否则就扯远了,下面就让我们通过实例体会delegate的基本作用吧。

有这么一个场景:

早恋是许多家长关心的问题啊,最近家长A貌似发现自己的孩子LiLei对家长B的孩子HanMeiMei有意思,同时家长B也发现了,为了确认情况,双方父母私下委托老师发现真实情况的时候通知一声,提早纠正学生的观念~。

简单代码模拟场景:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Delegate { class Program { static void Main(string[] args) { //家长A,B,他们不可能一天去学校监视孩子吧?委托给老师咯,自己还要去上班呢 Parent pa = new Parent(); Parent pb = new Parent(); //家长A,B分别委托老师发现早恋情况时通知他们 Teacher teacher = new Teacher(); teacher.NotifyStudentLove = pa.ReceiveMsg; teacher.NotifyStudentLove += pb.ReceiveMsg; //老师开始检查早恋情况 teacher.CheckLove(); } } }

老师类:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Delegate { public class Teacher { //声明一个委托类型,通知家长 public delegate void NotifyDelegate(string msg); //老师被吩咐了1个委托 //定义委托:在发现早恋时时通知家长(和事件只差一个event关键字噢!) public NotifyDelegate NotifyStudentLove; public void CheckLove() { //某一天AB同学突然发生纠纷!被老师发现啦! string msg = "A同学和B同学早恋啦!!"; //检查是否有家长委托老师通知早恋 if (NotifyStudentLove != null) { //果断通知家长 NotifyStudentLove(msg); } } } }

家长类:

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/70650.html