C#委托深度解析

一、委托的本质是什么呢?
从语法上看,委托是对方法的抽象封装,例如:public void print1(),public void print2(),我们可以抽象化,public delegate void Print();用Print p来声明,委托需要实例化和调用,类似于c++中的函数模板;
从功能上看,委托主要是方法的指针,用以方便实现函数的回调、调用(异步等)。
本质上,delegate是一个类,同关键字class和interface平级的,这个类中包含方法所属的类实例的地址、方法的地址,以及下个委托的引用(因此委托是链式结构的)。
二、委托的声明
C#中借用delegate关键字,C#的编译器一遇到delegate,就翻译成类似于函数模板的东西。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 action;public Func func;委托的方法必须在形式上和委托的声明一致
三、委托的赋值

//new 实现
public NoparamDelegate noParam = new NoparamDelegate(doSomething_forNoparamDelegate);   
//lambd表达式直接赋值 
public NoparamDelegate noparam_for_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();
    }
}

原文请参考:https://www.cnblogs.com/xietianjiao/p/9935361.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值