首先来看个小例子:
namespace 委托示例2 { /***** * 委托示例一 * 说明:此段程序主要是将委托作为方法的参数传入方法中,使得具体调用时再根据需要为方法赋值。 * * 关键点:利用委托将方法作为方法的参数 * * * * ******/ //委托的定义 //1,委托:委托出现的位置和string相同,所以GreetingDelegate应该也是个类型,但是委托的声明方式和类完全不同。 //2,委托在编译的时候确实会被编译成类,因为delegate是一个类,所以在任何可以生命类的地方都可以声明委托。 public delegate void GreetingDelegate(string name); class Program { static void Main(string[] args) { GreetPeople ("水田如雅",EnglishGreeting); GreetPeople ("vac",ChineseGreeting); Console.ReadKey(); } #region 没有定义委托方法时“问好”方式的调用 ///// <summary> ///// 用于向某人问好的方法,当传递代表某人姓名的name参数,比如jimmy进去的时候,在这个方法中,将会调用EnglishGreeting方法,再次传递name参数,Ehglish则用于向屏幕输出good,morning,jimmy ///// </summary> ///// <param name="name"></param> //public void GreetPeople(string name, Language lang) //{ // //做些额外的事情,比如初始化之类的,此处省略 // switch (lang) // { // case Language.English: // EnglishGreeting(name); // break; // case Language.Chinese: // ChineseGreeting(name); // break; // } // //EnglishGreeting(name); //} #endregion #region 用委托来实现问好方式的调用 //使用了委托之后,对GreetPeople方法进行的改进 public static void GreetPeople(string name, GreetingDelegate MakeGreeting) { MakeGreeting(name); } #endregion /// <summary> /// 英语的说早上好的方法 /// </summary> /// <param name="name"></param> /// <returns></returns> public static void EnglishGreeting(string name) { Console .WriteLine ("good,morning!"+name); } /// <summary> /// 汉语的问好方法 /// </summary> /// <param name="name"></param> /// <returns></returns> public static void ChineseGreeting(string name) { Console .WriteLine( "早上好,宝贝儿~~~" + name); } #region 有了委托之后就不在需要枚举了 ///// <summary> ///// 定义一个枚举,用来判断到底用哪个版本的Greeting问候方法合适 ///// </summary> //public enum Language //{ // English, Chinese //} #endregion } }
首先没有委托的时候,我们要定义一个枚举,将English,Chinese这两个变化点写进去,然后在具体的GreetPeople方法中进行调用的时候,我们要通过swich进行一个选择,但是,这样做只能应对暂时的平衡,当遇到变化的时候,比如增加个日式欢迎方法,我们又要回去改动switch方法。
在面向对象的设计思想中,我们以前用过很多设计模式来去除选择和应对变化,比如工厂,状态模式,命令模式,但是如果我们使用了委托,我们就可以将方法当做变量来处理,这样事情就变得非常简单,而且从整体结构上看,比加入设计模式容易得多。
首先来看示例:
namespace 将方法绑定到委托示例 { //委托的定义 //1,委托:委托出现的位置和string相同,所以GreetingDelegate应该也是个类型,但是委托的声明方式和类完全不同。 //2,委托在编译的时候确实会被编译成类,因为delegate是一个类,所以在任何可以生命类的地方都可以声明委托。 public delegate void GreetingDelegate(string name); class Program { static void Main(string[] args) { //既然委托GreetingDelegate和string类型一样,都是定义了一种参数类型,那么是不是也可以像下面这样使用委托。。。。。。 //so,尝试如下调用 //注意:1,“=”是赋值的语法;“+=”是绑定的语法; //.......2,如果第一次就是用“+=”就会出现使用了未赋值的局部变量的编译错误 #region 将委托作为变量 ////如下,我们将委托作为变量传入 //GreetingDelegate delegate1, delegate2; //delegate1 = EnglishGreeting; //delegate2 = ChineseGreeting; //GreetPeople("水田如雅", delegate1); //GreetPeople("vac", delegate2); //Console.ReadKey(); #endregion #region 委托搭载方法示例 //GreetingDelegate delegate1; //delegate1 = EnglishGreeting;//先向委托类型的变量赋值 //delegate1 += ChineseGreeting;//向此委托变量再绑定一个方法 ////将先后调用EnglishGreeting与ChineseGreeting方法 //GreetPeople("水田如雅", delegate1); //输出的name都是“水田如雅” //Console.ReadKey(); #endregion #region 通过委托直接调用方法 //GreetingDelegate delegate1; //delegate1 = EnglishGreeting; //委托变量的赋值 //delegate1 += ChineseGreeting;//在委托上再次绑定一个方法 ////将先后调用两个方法 //delegate1("水田如雅(vac)"); //Console.ReadKey(); #endregion #region 简化委托的调用 //GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);//委托的定义和赋值 //delegate1 += ChineseGreeting;//绑定方法 #endregion #region 取消委托的绑定示例 //GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting); //delegate1 += ChineseGreeting;//给委托绑定方法 ////先后调用EnglishGreeting和ChineseGreeting //GreetPeople("这是第一次调用", delegate1); //Console.WriteLine(); ////取消EnglishGreeting调用 //delegate1 -= EnglishGreeting;//取消对EnglishGreeting ////再次调用 //GreetPeople("第二次调用方法,注意看有几个方法被调用了。。。。。。", delegate1); //Console.ReadKey(); #endregion } #region 用委托来实现问好方式的调用 //使用了委托之后,对GreetPeople方法进行的改进 public static void GreetPeople(string name, GreetingDelegate MakeGreeting) { MakeGreeting(name); } #endregion /// <summary> /// 英语的说早上好的方法 /// </summary> /// <param name="name"></param> /// <returns></returns> public static void EnglishGreeting(string name) { Console.WriteLine("good,morning!" + name); } /// <summary> /// 汉语的问好方法 /// </summary> /// <param name="name"></param> /// <returns></returns> public static void ChineseGreeting(string name) { Console.WriteLine("早上好,宝贝儿~~~" + name); } } }
下面总结下委托的调用过程:
1,委托的调用都是先赋值,然后再搭载其他方法。
2,委托可以搭载方法,也可以将方法unload掉。
使用了委托后,我们可以在使用时简化调用并且做到灵活选择所调用的方法,委托可以替代以前接口或实现类在结构上利用多态实现方法调用时的灵活性,并在一定程度上简化调用方法。
未完待续。。。。。。。。。。
原文地址:http://blog.csdn.net/lhc1105/article/details/41787369