什么是委托?
委托(delegate)是一种托管方法的数据结构,它是一种引用类型,是对方法的引用。如果说int,string等是对数据类型的定义,那么委托就类似于对“方法类型”的定义,声明一个委托,就是声明一种方法签名,只要是和声明委托方法签名相同的方法,都可以被委托实例托管。那为什么叫委托呢,这个名字似乎看似和它的职责不相干,但其实这是很“面向对象”的称呼,一个方法自己办不到的事情,去让另一个方法帮他做,这两者之间的关系不就是委托吗,这样的抽象关系不就是面向对象的一部分吗。
如何声明一个委托?
委托的关键字是delegate ,由它开头,后边接返回值类型,委托名称以及参数具体如下:
delegate 返回值类型 委托名称 (方法参数)
如何使用委托?
声明一种委托类型,就像声明类一样,我们使用的时候需要先实例化,然后通过构造传参或者“+=”的方法为委托实例添加托管方法,委托可以托管多个方法。
首先,你要确保要添加的方法,是符合委托类型的,也就是方法签名要一致。判断方法签名是否一致的两个要素就是:返回值类型,参数类型、参数数量,这几项都要一一对应。
上方有三个测试方法,分别是无参数无返回值,有参,有返回值的方法。下面通过代码来体现委托的用法:
class Program { delegate void NoReturnNoArgsDele(); delegate int HasReturnNoArgsDele(); delegate int HasReturnAndArgsDele(int arg); static void Main(string[] args) { DelegateTest delegateTest = new DelegateTest(); //实例化委托,并通过构造器传入要委托的方法 NoReturnNoArgsDele noReturnNoArgs = new NoReturnNoArgsDele(delegateTest.NoReturnNoArgs); HasReturnNoArgsDele hasReturnNoArgs = new HasReturnNoArgsDele(delegateTest.HasReturnNoArgs); //委托内部重载了+= 和-=运算符,可以通过这两个运算符为委托对象添加或移除方法 hasReturnNoArgs+= delegateTest.HasReturnNoArgs; HasReturnAndArgsDele hasReturnAndArgs = new HasReturnAndArgsDele(delegateTest.HasReturnAndArgs); Console.WriteLine("Hello World!"); } }
声明了委托,那如何使用呢?委托的使用跟方法的调用一致:
另外,我们如果为委托实例添加多个方法,在调用委托时,就会根据添加顺序依次调用,这种通过委托一次性调用多个方法的过程,称作委托的多播。注意,如果如果是有返回值得委托,执行多播以后,委托的返回值是最后添加的方法的返回值。
Action和Func泛型委托
Action和Func泛型委托是微软为我们实现定义好的两组委托,这两组委托,足以满足我们的日常使用,而无需自己去定义委托。
先来了解一下它们的定义,
他们都是处于System命名空间下。
Func委托,它托管有返回值的方法,它的构造方法的重载有17个之多,也就是说,你可以用它匹配最多有16个参数的带有返回值的方法,这足以满足绝大多数我们使用委托的情景。
Action委托,它托管没有返回值的方法,同func委托一样,它可以最多匹配16个参数的无返回值方法。
由此,以上我们自定义的委托就可以换为以下代码:
把参数类型或者返回值类型(如果需要它们)写在尖括号中,它的实现原理是泛型,如果不明白泛型,请留意后期的文章。
委托在方法参数中的应用
如果你想实现方法的多样化定制,使用委托作为参数是必不可少的。
想通过一个方法实现不同的操作,可以动态的去改变代码逻辑,这就需要使用委托,用方法封装一些固定的逻辑,用委托方法写不同的代码逻辑,去实现多样化的需求,这就是委托的魅力所在。
个人公众号:DotNet 致知 ,愿我们一同进步。