委托,事件,回调,匿名函数与Lambda表达式详解

xiaoxiao2021-02-28  111

1.委托

听到很多人这样描述委托:比如说,你是一个程序,现在正在做一款产品,而需要用到的模型是你不会做的,于是你委托你的一位同事来帮你做模型部分。这就是委托,而中文的字面描述意思也是这样,委托委托,把你自己所不能做或者没时间做的事情交给其他人去做,而怎么知道是哪个人去做的,就需要我们告诉他。

委托在微软《C#编程指南》中是这样描述的  Delegate是表示对具有特定参数列表和返回类型的方法的引用的类型,对委托进行实例化后,委托会将对其进行的方法调用传递到该方法。当我们调用该实例化委托时就可以按封装的方法本身进行调用。委托的实质也就是这段话的字面意思。虽然有点绕口。。。

意思也就是,我们将一个方法注册给一个委托方法,当我们调用这个委托时就相当于调用了这个注册的方法。

写一个简单的小代码示范一下:

using System; using System.Collections.Generic; using System.Text; namespace TestApp { /// <summary> /// 委托 /// </summary> /// <param name="s1"></param> /// <param name="s2"></param> /// <returns></returns> public delegate string ProcessDelegate(string s1, string s2); class Program { static void Main(string[] args) { ProcessDelegate pd = new ProcessDelegate(new Test().Process);//将方法注册进委托 Console.WriteLine(pd("Text1", "Text2"));//调用该委托,就相当于调用了注册进委托的方法 } } public class Test { /// <summary> /// 方法 /// </summary> /// <param name="s1"></param> /// <param name="s2"></param> /// <returns></returns> public string Process(string s1, string s2) { return s1 + s2; } } }

2.事件

事件的描述: 在某件事情发生时,一个对象可以通过事件通知另一个对象。比如,前台完成了前台界面,他通知你,可以把前台和你开发的程序整合了。这就是一个事件。可以看出事件是在一个时间节点去触发另外一件事情,而另外一件事情怎么去做,他不会关心。就事件来说,关键点就是什么时候,让谁去做。 像在游戏开发中,用户出售了一个物品,这个时候触发了出售物品这个事件,相应的这个事件被处罚以后需要执行对应的方法,例如金币增加监听了这个事件,背包刷新也监听了这个事件,等等方法,只要是监听了这个事件的方法都会被调用。 c#中的事件是依靠委托来实现的,事件就是一种通知机制,当一件事情发生时(比如说状态改变)通知给相关的其他对象. 事件的代码例子这里就就不祥举了可以参考这篇博客 Event事件:只能在类内部触发,不能再累的外部触发。事件本质上是一种受限制的委托。

3.回调

回调函数就是一个通过函数指针调用的函数,如果你把函数的指针作为参数传递给另一个函数我们就说这是回调函数,简而言之就是将方法作为方法的参数调用就是回调函数。 代码就很简单了,一看就明白,不解释了 void Test() { Show(CallBack); } void CallBack() { } delegate void MyCallBack(); void Show(MyCallBack callback) { }

4.匿名函数

匿名函数也很好理解,就是简单的字面意思,没有名字的函数。。。 匿名函数有两种语法风格:Lambda表达式,匿名方法表达式 Lambda表达式: (匿名函数参数列表)=>(匿名函数的函数体;); 例如: 函数声明 (int x) => {return x + 1}; (int x ,int y) =>{return x * y}; //多参数  使用  delegate void TestDelegate(string s);  TestDelegate testDelC = (x) => { Console.WriteLine(x); }; 匿名方法表达式: delegate(匿名函数参数列表){代码块;}; 例如: 函数声明 delegate (int x) {return x + 1;} //匿名函数方法表达式  delegate {return 1 + 1;} //参数列表省略  delegate(){return 1+1;};无参 使用  TestDelegate testDelB = delegate(string s) {Console.WriteLine(s); }; 这里也对集合的排序方法写了个匿名函数

5.Action

1.Action是系统内置的一个委托类型,没有返回值,没有参数的方法。 例如 Action action; void Main(){ action =  Show; action(); } void Show(){}

2.使用Action指向一个有参数的方法

Action<int> a ;//定义一个委托类型,这个类型可以指向一个没有返回值有一个int参数的方法

Action<int> a; void Main(){ a =  Show; a(1); } void Show(int i){ prit(i); } 采用重载方法,action注册会自动找到对应的重载方法

通过在Action后指定泛型 定义委托的参数

6.Func

1.Func是带有返回值的委托类型 Func<int> func;//返回值为int的委托类型,需要对应一个返回值为int,参数为空的方法 void Main(){ func = Show; print(func()); } int Show(){ return 1; } 2.带有返回值有参数的委托类型 Func<int,string>a ;//返回值为string类型,参数为int的委托类型。 void Main(){ func = Show; print(func(1)); } string Show(int s){ return s.tostring(); } Func委托<>反省列表中,最后一个为方法的返回值类型,前几项为方法的参数列表,参数列表最多有16个。 Func和Action是系统预定义的委托类型,用这两个委托基本可以涵盖所有的委托类型。当然我们也可以使用deleget自己定义。

7.多播委托

Action a; void Main(){ a=Test; a+=Test2;//表示添加一个委托的引用 //a-=Test; 取消一个委托的引用 a(); //委托指向了两个方法,此时会调用这两个方法, 当委托的方法出现异常时会停止迭代 //手动执行委托中的方法 Deleget[] delegets = a.GetInvocationList(); foreach(Deleget de in delegets ){ de.DynamicInvoke(); } } void Test(){} void Test2(){}
转载请注明原文地址: https://www.6miu.com/read-32029.html

最新回复(0)