上位机C#中委托(delegate)与事件(event)的快速理解 您所在的位置:网站首页 c语言委托讲解 上位机C#中委托(delegate)与事件(event)的快速理解

上位机C#中委托(delegate)与事件(event)的快速理解

2023-06-29 20:03| 来源: 网络整理| 查看: 265

关于委托(delegate)

有人说委托是函数指针,对于没有C++基础的人很难理解什么函数指针。在我看来委托是一类相同函数(返回值类型与参数列表一致)的链表。什么是返回值类型与参数列表一致的函数?这个很容易理解。如以下代码所示:

void showName(string name) { } void showTitle(string title) { }

或者如下:

int plus(int x,int y) { return x + y; } int mult(int x, int y) { return x * y; }

上面说了委托是链表。然后你在声明委托的时候,要说明链表中函数的返回类型与参数列表,比如我声明返回类型为void,参数列表为string的委托。

delegate void func(string f); //我声明的func与下面两个函数返回类型与参数列表一致 void showName(string name) { } void showTitle(string title) { } delegate int func2(int x, int y); //我声明的func2与下面两个函数返回类型与参数列表一致 int plus(int x,int y){ return x + y; } int mult(int x, int y) { return x * y; }

上面提到很多“委托”这个词,其实后面还有省略的两个字“类型”。你声明委托是声明了一种类型。声明以后就可以把该类型当参数传入。

delegate void func(); void showName(func name) { }

以上func name并没有报错因为声明委托结束,代码中就有了func这个类型。既然有类型,那么我们就可以根据类型生成实例。比如

delegate void func(); func l;

我们定义了一个返回值为void,无参数的func类型的链表。然后声明了一个具体实例l。这里用l就是list的意思,帮助大家容易理解。然后就可以往链表里添加函数。使用符号“+=”

delegate void func(string f); static func l; static void showName(string name) { } static void showTitle(string title) { } static void Main(string[] args) { //这里两个函数要加static(静态的)不然需要你通过具体类来引用,委托同理。 l += showName; l += showTitle; }

通过以上操作,你就在函数链表l添加了showName与showTitle两个函数。这里很像长鞭炮,你把函数串联起来了。如果你调用l这个委托,就相当于点燃了引线,所有函数就会依次运行一遍。

delegate void func(string f); static func l; static void showName(string name) { Console.WriteLine("你先输出了名字,参数:"+name); } static void showTitle(string title) { Console.WriteLine("你又输出了主题,参数:"+title); } static void Main(string[] args) { l += showName; l += showTitle; l("一个参数"); Console.ReadKey(); }

当然你可以传入函数,在调用函数,效果一样。

delegate void func(string f); static func l; static void showName(string name) { Console.WriteLine("你先输出了名字,参数:"+name); } static void showTitle(string title) { Console.WriteLine("你又输出了主题,参数:"+title); } static void run(func l) { l("一个参数"); } static void Main(string[] args) { l += showName; l += showTitle; run(l); Console.ReadKey(); }

链表模型(l的模型)

showName()showTitle()

如果使用=号将清空链表,使链表中只剩最后一个等号后的函数。也可以使用-=,来清除对应的函数。这里请大家自行测试。

具有返回值的委托类型,返回值默认是最后一个函数的返回值,就是最后添加的返回值。

delegate int func(int j,int k); static func l; static int plus(int x,int y){ return x + y; } static int mult(int x, int y) { return x * y; } static void Main(string[] args) { l += plus; l += mult; Console.WriteLine(l(4,5)); Console.ReadKey(); }

运行以上返回值是20,结果是最后一个函数返回值。如何获取每个函数的返回值,这里写了一个示例:

delegate int func(int j,int k); static func l; static int plus(int x,int y){ return x + y; } static int mult(int x, int y) { return x * y; } static void Main(string[] args) { l += plus; l += mult; foreach(Delegate i in l.GetInvocationList()){ func k=(func)i; Console.WriteLine(k(4,5)); } Console.ReadKey(); }

委托就讲到这里,重新概括一下就是

委托是一种类型委托是一种类型与返回值相同函数的链表委托使用+=,=,-=三个符号操作链表里的函数调用委托就会依次调用委托链表里的所有函数委托返回值默认是最后一个添加的函数返回值 关于事件(event)

事件是一种特殊的委托,事件需要与类结合起来理解。

首先明确关键字event在实例化委托时使用而非定义委托时使用。

委托定义与使用

delegate void func(); static func l;

 

注意关键字的位置,在实例化的时候使用event;

事件需要与类结合起来,定义事件的类才可以调用事件。

delegate void func(); class Program { static void Main(string[] args) { Person.l();//这里报错Person.l”只能出现在 += 或 -= 的左边(从类型“Person”中使用时除外) Console.ReadKey(); } } class Person{ public static event func l;//这里定义事件 void Action() { l();//这里没有报错因为这里在定义事件的类里。 } }

之前讲过,委托就像是一串鞭炮。将函数链接与取消或者触发,可以自由使用。但是事件限定了只能由声明事件的类来触发。而链接函数的过程,可以看做一种通知。这里写一个黑人抬棺的例子帮助大家理解

using System; using System.Data; using System.IO; namespace ConsoleApp3 { delegate void func(string name); class Program { static void Main(string[] args) { Person Hei1 = new Person("黑人小哥1"); Person Hei2 = new Person("黑人小哥2"); Person Hei3 = new Person("黑人小哥3"); Person Hei4 = new Person("黑人小哥4"); Person ming = new Person("小明"); ming.died += Hei1.taiGuan; ming.died += Hei2.taiGuan; ming.died += Hei3.taiGuan; ming.died += Hei4.taiGuan; ming.fellFull += Hei1.seeFull; ming.fellFull += Hei2.seeFull; ming.fellFull += Hei3.seeFull; ming.fellFull += Hei4.seeFull; ming.fellHungry += Hei1.seeHungry; ming.fellHungry += Hei2.seeHungry; ming.fellHungry += Hei3.seeHungry; ming.fellHungry += Hei4.seeHungry; ming.EatDonut(10); Console.ReadKey(); } } class Person{ string name; public event func died; public event func fellFull; public event func fellHungry; public Person(string name) { this.name = name; } public void EatDonut(int i){ if (i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有