详解C#中的委托

2019-12-30 15:48:30刘景俊

委托这个东西不是很好理解,可是工作中又经常用到,你随处可以看到它的身影,真让人有一种又爱又恨的感觉,我相信许多人被它所困扰过。

一提到委托,如果你学过C语言,你一定会马上联想到函数指针。

什么是委托?委托是C#中类型安全的,可以订阅一个或多个具有相同签名方法的函数指针。委托可以把函数做为参数传递,其实际意义便是让别人代理你的事情。委托可以看做是函数的指针,整数可以用整数变量指向它,对象可以用对象变量指向它,

函数也可以用委托变量指向它。我们可以选择将委托类型看做只定义了一个方法的接口,而委托的实例可以看做是实现了那个接口的一个对象。

使用委托,必须满足4个条件:

声明委托类型; 必须有一个方法包含了要执行的代码; 必须创建一个委托实例; 必须调用(invoke)委托实例。

委托的申明

声明委托的方式:delegate 返回值类型 委托类型名(参数)

委托的申明和接口方法的申明基本上一致,只是在返回类型关键字的前面多了一个delegate关键字。还有就是委托一般声明为public类型,因为它随时要供别人调用的。

委托的本质也是一个类型。我们声明一个类可以进行实例化,同样委托也可以进行实例化。

有如下四种委托:


//1.无参数无返回值
    public delegate void NoParaNoReturnEventHandler();
    //2.有参数无返回值
    public delegate void WithParaNoReturnEventHandler(string name);
    //3.无参数有返回值
    public delegate string NoParaWithReturnEventHandler();
    //4.有参数有返回值
    public delegate string WithParaWithReturnEventHandler(string name);

如果代码想要执行操作,但不知道操作细节,一般可以使用委托。例如, Thread类之所以知道要在一个新线程里运行什么,唯一的原因就是在启动新线程时,向它提供了一个ThreadStart或ParameterizedThreadStart委托实例。


Thread th = new Thread(Test);
th.Start();
public Thread(ThreadStart start);
public delegate void ThreadStart();

ThreadStart是一个无参无返回值的委托。


    static void Test()
    {
      Console.WriteLine("线程方法");
    }

这个Test方法的函数签名必须和委托ThreadStart的函数签名一致。

委托的调用

必须先实例化委托,然后再调用。

函数的签名和委托的签名必须一致。NoParaNoReturnEventHandler _NoParaNoReturnEventHandler = ConsoleInfo;,编译器帮我们进行了new,但是不能写成NoParaNoReturnEventHandler _NoParaNoReturnEventHandler = ConsoleInfo();

因为这样就成为了函数调用。