C#深度学习の委托深度解析
一、我们在使用C#的过程中,不可避免的用到了委托。
委托的本质是什么呢?
从语法上看,委托是对方法的抽象封装,例如:public void print1(),public void print2(),我们可以抽象化,public delegate void Print();用Print p来声明,委托需要实例化和调用,类似于c++中的函数模板;
从功能上看,委托主要是方法的指针,用以方便实现函数的回调、调用(异步等)。
直观上,委托的作用有方法(函数)回调、方法(函数)接收值(listener),方法(函数)多线程调用、传值等等。
本质上,delegate是一个类,同关键字class和interface平级的,这个类中包含方法所属的类实例的地址、方法的地址,以及下个委托的引用(因此委托是链式结构的)。
以下我们以实例展开委托声明、实例化、调用等技巧。
二、委托的声明
C#中借用delegate关键字,C#的编译器一遇到delegate,在翻译C#的时候就被翻译成类似于函数模板的东西。delegate刻意定义在类的内部,也可以定义在外部,和类没有关系。
public delegate void Print(); //无参数,无返回值的委托 public delegate <out string>Print(); //无参数,返回string的委托 public delegate<out string,in string>Print(string str); //string参数,返回string的委托 .net3.5,系统定义了无参和有参的委托Action和Func关键字 public Action 本质就是public delegate void的转定义 public Func 本质是public delegate <out string>
用法:
public Action<string> action; public Func<string> func;
委托的方法必须在形式上和委托的声明一致
三、委托的赋值
public NoparamDelegate noParam = new NoparamDelegate(doSomething_forNoparamDelegate); //new 实现 public NoparamDelegate noparam_for_lambd = () => //lambd表达式直接赋值 { Console.WriteLine("no param,form lambd,test"); }; public NoparamDelegate noparam_for_function = doSomething_function; //方法直接赋值 public static void doSomething_forNoparamDelegate() { Console.WriteLine("no param,form test"); } public static void doSomething_function() { Console.WriteLine("no param,form function, test"); }
四、委托的调用
//委托调用-普通方法
doSomething();
//委托调用invoke
doSomething?.Invoke();
oneParam?.Invoke("one param,form test");
//异步调用
doSomething?.BeginInvoke(complete, null); //object标识附加信息 IAsyncResult ret = func_oneparam?.BeginInvoke("transmit赋值,异步调用,", null, null); //ret.IsCompleted, ret.AsyncWaitHandle.WaitOne(100)等用于轮询过程 Console.WriteLine("开始其他工作!.."); string strRet = func_oneparam?.EndInvoke(ret); Console.WriteLine(strRet);
委托的BeginInvoke有两个或三个参数(重载)
param1:string,参数
param2:回调函数,异步方法完成后调用
param3:object形式的附加信息
返回值:IAsyncResult 类型,我们记作ret
ret中有属性IsCompleted和AsyncWaitHandle,可以用以轮询异步方法调用的方法
string strRet = func_oneparam?.EndInvoke(ret); //在需要的地方获取异步执行结果,如果没执行完,将阻塞调用线程,直至获取结果
五、委托链
对于多个委托方法,.net定义了委托链的概念
Delegate主要定义了Combine(简写+=),Remove(简写-=)等方法
Action delegateSet = null;
delegateSet = (Action)Delegate.Combine(actionChainOne,actionChainTwo);
下面是一段示例代码:
public class Test { public delegate void Print(); Print p; public void method1() { Console.WriteLine("m 1"); } public void method2() { Console.WriteLine("m 2"); } public void method3() { Console.WriteLine("m 3"); } public void method4() { Console.WriteLine("m 4"); } public void combine() { p += method1; p += method2; p += method3; p += method4; } public void run() { Delegate[] myDelegates = p.GetInvocationList(); foreach (var myDelegate in myDelegates) { Print m1 = (Print)myDelegate;//注意此处需强转 m1.Invoke(); } } } class Program { static void Main(string[] args) { Test test = new Test(); test.combine(); test.run(); Console.ReadKey(); } }
有交流沟通,请加群:568055323
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧