众所周知,winform也好,webform也好,里面随处可见的事件驱动,有事件,当然也少不了委托,感觉之前对委托这个概念的理解一直是模模糊糊的,口里都会背的那么几句话:“委托可以把方法当作参数在另一个方法中传递和调用”,“委托是方法的快捷方式”等等。但是真要深入理解,灵活运用,还是要有良好的代码理解功底和面向对象基础的,今天就再来把委托这个知识梳理梳理,以加深对它的理解。
要理解委托,我们首先要知道委托的概念:
”委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。“
这是百度上和许多教科书上都有的一个概念,但是初学这门编程语言的话,或者基础比较差的童鞋,看到这句话,肯定是一脸懵比,先不用着急,我们来慢慢通过代码去理解委托这个概念
(1)首先新建一个控制台程序,对于初学者而言,控制台程序是学习基础知识的最好工具
//delegate void EvenHandler(object sender, EventArgs e); public delegate void MyDel();//自定义一个委托 class Program { static void Main(string[] args) { //(1)简单委托 MyDel say1 = SayHi; MyDel say2 = new MyDel(SayHi); say1(); say2(); } static void SayHi() { Console.WriteLine("Hi World"); } }
这是最简单的委托实例了,委托可以通过上面say1和say2两种方式进行调用,这里我们要知道委托也是一种类型,所以它和类是同级的,可以通过委托来掉用方法,不要误以为委托和方法同级的,方法只是类的成员,还有定义委托和与之对应的方法必须具有相同的方法签名,即参数个数,类型相同,返回值类型相同,上面代码实例没有什么实际意义,只是然我们知道委托的结构以及委托与方法的关系
(2)委托的扩展
//自定义一个委托 public delegate int Expression(int a, int b); class Program { static void Main(string[] args) { //(2)委托扩展 //Expression ex = GetEX; //Calculate(ex, 25, 10); Calculate(GetAdd, 25, 10); } static int Add(int a, int b) { return a + b; } static int Divide(int a, int b) { return a / b; } static int subtract(int a, int b) { return a - b; } static int multiply(int a, int b) { return a * b; } static int GetAdd(int a, int b) { return a + b; } static void Calculate(Expression ex, int a, int b) { Console.WriteLine(ex(a, b) + " "); } }
和之前比,稍微把代码复杂了那么一点点,上面我们真正实现了“把方法当作参数在另一个方法中传递或调用”,实现了一个简单的加法方法,当然我们也写了减法,乘法,除法的方法。你会想这样写有什么好处呢?我直接调用自己的加减乘除方法不就完了吗,何必要多此一举,通过委托来折腾一番呢?委托的意义何在呢?在这里请先听我先说一种思想:“上面的Calculate方法里面代码比较少,只有一个简单的输出语句,而且我们只想单纯的实现一个简单加减乘除效果,所以你会感觉有点多次一举,也可以说本来就是多次一举,但是你可以设想一下,假如我们这几个加减乘除方法,它的代码量非常庞大,但是这几个方法的代码相似度又非常高,但是每个方法里就只有一两个小小的语句块儿不一样,那不是会让你觉得很不爽,很想把它们整合,那怎么处理呢?你可能首先会想通过if,else if或者switch语句对不同部分的代码块做不同的处理,现在我只需要做加减乘除四个case,这个思路暂且可以接受,那将来我又要加余数运算,平方运算,指数对数运算等等,假设我几百个甚至更多个这样类似的方法呢,那我岂不是要写几百个if,else,这样做很明显程序的扩展性会很差。所以我们要换个思路,我们完全可以通过一个方法把相同的部分封装起来,而不同的部分通过参数传过去,但是方法并不能直接被当作参数被传递和调用,那怎么办呢?,那么这时候委托的作用就体现出来了,我们可以把委托作为参数传递给封装好了的方法,通过委托来动态的调用方法。” 结合我所说的思想,那么上面封装的部分就类似与我们的Calculate方法,而不同的部分就是每个加减乘除方法,你可以假设Calculate是一个非常庞大的已经封装好了的方法,而我们传进去的只是这个方法需要动态改变的部分,这样就是最上面概念所谓的“方法动态地赋给参数”,这样写到好处是大大提升了方法的灵活性与扩展性,也减少了代码的冗余,所以委托在实际项目中是一个十分有用的工具