在开发过程中我们总会听到“委托”这个东西,尤其是在这次的高校云平台中。那么我们今天就来一探究竟:
从字面上来讲,委托有代理的意思:A委托B去买东西,那么B就是A的代理去执行“买东西”这个行为。但是从程序上来讲,委托是一种引用方法的类型,委托方法可以像其他任何方法一样。简单地说就是,委托是一种数据类型,它的变量可以引用到某一个符合要求的方法上,通过委托可以间接地调用该方法。
下面来看一个例子:
在不使用委托的情况下,我们要实现“使用英汉两种自我介绍”的效果,我们就要首先定义两个自我介绍的方法:英语介绍和汉语介绍两种:
/// <summary> /// the English speaker:英语介绍方式 /// </summary> /// <param name="name">The name.</param> public void EnglishSpeaker(string name) { Console.WriteLine( string.Format("Hello my name is {0} and I am English speaker.\n", name)); } /// <summary> /// the Chineses speaker:汉语介绍方式 /// </summary> public void ChineseSpeaker(string name) { Console.WriteLine( string.Format("您好我的名字叫{0},我是讲普通话的。\n", name)); }
定义好两个方法之后,我们来编写主函数,调用两种方法实现不同语言的自我介绍:
/// <summary> /// 根据上下文调用不同的方法 /// </summary> /// <param name="name">string</param> /// <param name="lang">enum</param> private static void Say(string name, Language lang) { switch (lang) { case Language.Chinese: Program.ChineseSpeaker(name); break; case Language.English: Program.EnglishSpeaker(name); break; default : break; } }
而在主函数中我们要使用Switch……case 或者if……else来判断是使用英语自我介绍还是汉语的自我介绍。但是,如果我们现在想要增加一种阿拉伯语的自我介绍方式,虽然可以再增加一个自我介绍的方法,并且在主函数中通过增加case语句来增加调用的情况。那么问题来了,只要增加自我介绍的语言时,我们就要写一个相应语言的函数吗?那么,我们程序的主函数中将会有N个case语句,来列举我们需要的N个语言的自我介绍。
当然不是。因为这样不但不利于系统的扩展和维护,而且对面向对象的思想也有所违背。所以,我们就要使用委托这一方法。
首先我们定义一种委托类型SpeakDelegate,然后通过say方法看看如何使用委托变量。
<span style="font-size:18px;"> Private delegate void SpeakDelegate(string name);</span>
然后我们通过修改Say方法来使用委托变量:
private static void Say(String name,SpeakDelegate speaker{ speaker(name); }
最后我们在程序的主函数中就可以直接这么写:
<span style="font-size:18px;"> Program.Say("张三",<strong><span style="color:#ff0000;">ChineseSpeaker</span></strong>); //传递函数名进行委托方法的绑定 Program.Say("zhangsan",EnglishSpeaker); Program.Say("みょうじ",JapanSpeaker);
经过修改,我们的函数名已经被作为了Say方法的参数,而这也就是委托的思想了。
相比之前的,主函数中有效地消除了“Switch …… case”的判断语句,程序变得简单,也开始符合OOP中的开闭原则。而且使用委托的技术之后,参数已经不再是委托类型,而是一个委托类型变量。现在我们调用Say方法只需要传递一个name和具体的实现函数名就可以了。