四、委托
4.1、什么是委托,委托的本质是什么呢?
1、形似一个方法,用delegate修饰符修饰。
| 所谓委托,ILSpy反编译识别底层----生成一个一个的类。如果定义在class外部:独立生成一个类,如果定义在class内部,生成了一个类中类:包含一个 |
2、所以委托的本质:就是一个类。
4.2、委托的实例化,执行委托
1、实例化一个委托,必须传入一个和当前委托的参数和返回值完全吻合的方法
2、如果执行委托-----执行Invoke方法,就会把指向这个委托的方法给执行掉;
形态上理解下委托:委托---->类,用invoke执行方法(方法可以把一段业务逻辑丢给委托,也就是lamdaba表达式--->匿名函数)
| namespace D_MyDelegate |
| { |
| |
| |
| |
| public delegate void NoReturnNoParaOutClass(); |
| public class CustomDelegate |
| { |
| #region 定义委托 |
| |
| |
| |
| public delegate void NoReturnNoPara(); |
| |
| |
| |
| |
| public delegate void NoReturnWithPara(int x, int y); |
| |
| |
| |
| |
| |
| public delegate int WithReturnWithPara(int x); |
| |
| |
| |
| |
| |
| |
| public delegate int WithReturnNoPara(out int x, ref int y); |
| #endregion |
| |
| |
| |
| |
| public void Show() |
| { |
| { |
| |
| NoReturnNoPara method = new NoReturnNoPara(NoReturnNoParaMethod); |
| method.Invoke(); |
| var res = method.BeginInvoke(null, null); |
| |
| method.EndInvoke(res); |
| } |
| { |
| NoReturnWithPara method = new NoReturnWithPara(NoReturnWithParaMethod); |
| method.Invoke(1, 0); |
| } |
| { |
| WithReturnWithPara method = new WithReturnWithPara(WithReturnWithParaMethod); |
| int a = method.Invoke(1); |
| Console.WriteLine(a); |
| } |
| { |
| WithReturnNoPara method = new WithReturnNoPara(WithReturnNoParaMethod); |
| int x; |
| int y = 2; |
| int a; |
| a = method.Invoke(out x, ref y); |
| } |
| } |
| |
| public void NoReturnNoParaMethod() |
| { |
| Console.WriteLine("this is NoReturnNoPara"); |
| } |
| |
| public void NoReturnWithParaMethod(int x, int z) |
| { |
| Console.WriteLine("this is NoReturnWithPara"); |
| } |
| public int WithReturnWithParaMethod(int x) |
| { |
| Console.WriteLine("this is WithReturnWithParaMethod"); |
| return x; |
| } |
| public int WithReturnNoParaMethod(out int x, ref int y) |
| { |
| return x = y = 0; |
| } |
| } |
| } |
| |
4.3、委托的作用和意义(可以怎么用?使用场景?)
| { |
| Student student = new() { ID = 1, Name = "凭栏听雨", Age = 28 }; |
| student.SayHi(); |
| |
| |
| |
| |
| |
| |
| |
| |
| student.SayHiShanXi(); |
| student.SayHiGuangDong(); |
| student.SayHiBeiJing(); |
| |
| |
| student.SayHiByPara(UserType.BeiJing); |
| student.SayHiByPara(UserType.ShanXi); |
| student.SayHiByPara(UserType.GuangDong); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| DoHandleDelegate doHandleBeiJing = new DoHandleDelegate(student.SayHiBeiJing); |
| student.SayHiPrefect(doHandleBeiJing); |
| DoHandleDelegate doHandleShanXi = new DoHandleDelegate(student.SayHiShanXi ); |
| student.SayHiPrefect(doHandleShanXi); |
| DoHandleDelegate doHandleGuangDong = new DoHandleDelegate(student.SayHiGuangDong); |
| student.SayHiPrefect(doHandleGuangDong); |
| |
| } |
| using System; |
| using System.Collections.Generic; |
| using System.Linq; |
| using System.Text; |
| using System.Threading.Tasks; |
| |
| namespace D_MyDelegate |
| { |
| public class Student |
| { |
| public int ID { get; set; } |
| public string Name { get; set; } |
| |
| public int Age { get; set; } |
| |
| public void SayHi() |
| { |
| Console.WriteLine("你好"); |
| } |
| |
| |
| |
| |
| public void SayHiBeiJing() |
| { |
| Console.WriteLine("你好,喝豆汁儿去?"); |
| } |
| public void SayHiGuangDong() |
| { |
| Console.WriteLine("靓仔,嗦粉哟?"); |
| } |
| public void SayHiShanXi() |
| { |
| Console.WriteLine("弄撒恰?"); |
| } |
| |
| public void SayHiByPara(UserType userType) { |
| switch (userType) |
| { |
| case UserType.BeiJing: |
| Console.WriteLine("你好,喝豆汁儿去?"); |
| break; |
| case UserType.GuangDong: |
| Console.WriteLine("靓仔,嗦粉哟?"); |
| break; |
| case UserType.ShanXi: |
| Console.WriteLine("弄撒恰?"); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| public delegate void DoHandleDelegate(); |
| public void SayHiPrefect(DoHandleDelegate doHandle) { |
| |
| doHandle.Invoke(); |
| Console.WriteLine("一起勾肩搭背吃早饭!"); |
| } |
| } |
| |
| public enum UserType { |
| |
| BeiJing = 1, |
| GuangDong = 2, |
| ShanXi = 3 |
| } |
| } |
| |
4.4、微软内置委托 Action、Func
| |
| { |
| |
| |
| Action<int> action = new Action<int>(i => { }); |
| |
| Action<int, string> action1 = new Action<int, string>((i, s) => { }); |
| |
| Action<int, string, DateTime, double, float, object, decimal, StringBuilder, |
| int, string, DateTime, double, float, object, decimal, StringBuilder> action2 = null; |
| |
| |
| |
| |
| Func<int> func = new Func<int>(() => { return 10; }); |
| |
| Func<int, string> func1 = new Func<int, string>(i => { return ""; }); |
| Func<int, string, DateTime, double, float, object, decimal, StringBuilder, |
| int, string, DateTime, double, float, object, decimal, StringBuilder, int> func2 = null; |
| |
| Func<(int, string)> func3 = new Func<(int, string)>(() => { return (10, "你好"); }); |
| } |
4.5、委托的嵌套使用,Asp.net Core中间件的核心设计,委托的多重嵌套
| namespace D_MyDelegate |
| { |
| public class DelegateExtension |
| { |
| |
| |
| |
| public static void Show() |
| { |
| InvokeAction invokeAction = new InvokeAction(); |
| invokeAction.ExeMethod(); |
| |
| |
| Action action = new Action(invokeAction.ExeMethod); |
| |
| |
| |
| |
| Action<Action> action2 = new Action<Action>(ExecNextMethod); |
| action.Invoke(); |
| } |
| |
| public static void ExecNextMethod(Action action) |
| { |
| Console.WriteLine("Exec ExeMethod Before"); |
| action.Invoke(); |
| Console.WriteLine("Exec ExeMethod After"); |
| } |
| } |
| |
| public class InvokeAction |
| { |
| public void ExeMethod() |
| { |
| |
| Console.WriteLine("Exec ExeMethod"); |
| |
| } |
| } |
| } |
| |
| |
| namespace D_MyDelegate |
| { |
| public class DelegateExtension |
| { |
| |
| |
| |
| |
| |
| public static void Show() |
| { |
| InvokeAction invokeAction = new InvokeAction(); |
| |
| |
| |
| Action action = new Action(invokeAction.ExeMethod); |
| |
| |
| |
| |
| Action<Action> action2 = new Action<Action>(ExecNextMethod); |
| |
| |
| Func<Action, Action> func2 = new Func<Action, Action>(ExecNextMethod001); |
| action = func2.Invoke(action); |
| |
| Func<Action, Action> func3 = new Func<Action, Action>(ExecNextMethod002); |
| action = func3.Invoke(action); |
| |
| Func<Action, Action> func4 = new Func<Action, Action>(ExecNextMethod003); |
| action = func4.Invoke(action); |
| |
| action.Invoke(); |
| |
| } |
| |
| public static void ExecNextMethod(Action action) |
| { |
| Console.WriteLine("Exec ExeMethod Before"); |
| action.Invoke(); |
| Console.WriteLine("Exec ExeMethod After"); |
| } |
| |
| public static Action ExecNextMethod001(Action action) |
| { |
| return new Action(() => |
| { |
| Console.WriteLine("Exec ExecNextMethod001 Before"); |
| action.Invoke(); |
| Console.WriteLine("Exec ExecNextMethod001 After"); |
| }); |
| } |
| public static Action ExecNextMethod002(Action action) |
| { |
| return new Action(() => |
| { |
| Console.WriteLine("Exec ExecNextMethod002 Before"); |
| action.Invoke(); |
| Console.WriteLine("Exec ExecNextMethod002 After"); |
| }); |
| } |
| public static Action ExecNextMethod003(Action action) |
| { |
| return new Action(() => |
| { |
| Console.WriteLine("Exec ExecNextMethod003 Before"); |
| action.Invoke(); |
| Console.WriteLine("Exec ExecNextMethod003 After"); |
| }); |
| } |
| } |
| |
| public class InvokeAction |
| { |
| public void ExeMethod() |
| { |
| |
| Console.WriteLine("Exec ExeMethod"); |
| |
| } |
| } |
| } |
| |
通过循环的方式,一次性获取所有的特性,将要核心方法前后增加的内容,封装成为一个特性,标记在核心方法上。就可以实现无限制扩展,而不需要改动任何代码。
| namespace D_MyDelegate |
| { |
| public class DelegateExtension |
| { |
| |
| public void Show() |
| { |
| InvokeAction invokeAction = new InvokeAction(); |
| Action action = () => { invokeAction.ExeMethod(); }; |
| Type type = invokeAction.GetType(); |
| if (type.IsDefined(typeof(ActionBefor), true)) |
| { |
| foreach (BaseAttribute attribute in type.GetCustomAttributes(typeof(BaseAttribute), true)) |
| { |
| action = attribute.Do(action); |
| } |
| } |
| action.Invoke(); |
| } |
| |
| |
| } |
| |
| public class InvokeAction |
| { |
| [ActionBefor] |
| [ActionAfter] |
| public void ExeMethod() |
| { |
| |
| Console.WriteLine("Exec ExeMethod,这里是原始的方法,原始逻辑"); |
| |
| } |
| } |
| |
| public abstract class BaseAttribute : Attribute |
| { |
| public abstract Action Do(Action action); |
| } |
| public class ActionBefor : BaseAttribute |
| { |
| public override Action Do(Action action) |
| { |
| return new Action(() => |
| { |
| { |
| Console.WriteLine("我在这里扩充了一些自己的东西。。。"); |
| } |
| action.Invoke(); |
| }); |
| } |
| } |
| |
| public class ActionAfter : BaseAttribute |
| { |
| public override Action Do(Action action) |
| { |
| return new Action(() => |
| { |
| { |
| Console.WriteLine("我在这里扩充了一些自己的东西000011。。。"); |
| } |
| action.Invoke(); |
| }); |
| } |
| } |
| } |
| |
4.6、多播委托
| namespace D_MyDelegate |
| { |
| public class CustomMulticastDelegation |
| { |
| public void Show() |
| { |
| Action action = new Action(DoNothing); |
| |
| |
| |
| |
| |
| action += DoNothing; |
| action += DoNothingStatic; |
| action += new Student().SayHi; |
| action += () => { Console.WriteLine("这是lambda"); }; |
| |
| action -= DoNothing; |
| action -= DoNothingStatic; |
| action -= new Student().SayHi; |
| action -= () => { Console.WriteLine("这是lambda"); }; |
| |
| |
| action.Invoke(); |
| |
| } |
| |
| private void DoNothing() |
| { |
| Console.WriteLine("什么也没做"); |
| } |
| private static void DoNothingStatic() |
| { |
| Console.WriteLine("什么也没做"); |
| } |
| } |
| } |
| |
4.7 委托实现观察者模式
| using System; |
| |
| namespace MyDelegate.Event |
| { |
| public class Dog : IObject |
| { |
| |
| |
| |
| |
| |
| |
| public void DoAction() |
| { |
| this.Wang(); |
| } |
| public void Wang() |
| { |
| Console.WriteLine("{0} Wang", this.GetType().Name); |
| } |
| } |
| } |
| |
| using System; |
| |
| namespace MyDelegate.Event |
| { |
| |
| |
| |
| public class Mother : IObject |
| { |
| public void DoAction() |
| { |
| this.Wispher(); |
| } |
| public void Wispher() |
| { |
| Console.WriteLine("{0} Wispher", this.GetType().Name); |
| } |
| } |
| } |
| |
| using System; |
| |
| namespace MyDelegate.Event |
| { |
| public class Mouse : IObject |
| { |
| public void DoAction() |
| { |
| this.Run(); |
| } |
| public void Run() |
| { |
| Console.WriteLine("{0} Run", this.GetType().Name); |
| } |
| } |
| } |
| |
| namespace MyDelegate.Event |
| { |
| public interface IObject |
| { |
| void DoAction(); |
| } |
| } |
| |
| using System; |
| using System.Collections.Generic; |
| using System.Linq; |
| using System.Text; |
| using System.Threading.Tasks; |
| |
| namespace MyDelegate.Event |
| { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public class Cat |
| { |
| |
| |
| |
| public List<IObject> ObserList=new List<IObject>(); |
| public void MiaoObserver() |
| { |
| Console.WriteLine($"{this.GetType().Name} MiaoObserver========"); |
| |
| foreach ( IObject item in ObserList ) |
| { |
| item.DoAction(); |
| } |
| } |
| |
| |
| |
| public Action ActionHander; |
| public void Miao() |
| { |
| |
| Console.WriteLine($"{this.GetType().Name} Miao========"); |
| ActionHander.Invoke(); |
| } |
| |
| |
| |
| |
| |
| public event Action ActionHanderEvent; |
| public void MiaoEvent() |
| { |
| Console.WriteLine($"{this.GetType().Name} MiaoEvent========"); |
| ActionHanderEvent.Invoke(); |
| } |
| |
| |
| |
| |
| |
| |
| } |
| |
| public class ChildCat : Cat |
| { |
| public void Show() |
| { |
| |
| |
| |
| |
| } |
| } |
| } |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?