C#学习笔记(八)

第8讲委托2
  现在接着上一节的笔记委托1来讲,上一节委托1主要讲解了委托对静态方法的代理。那么这一节课我们就主要讲一下委托如何代理动态的方法。听了上节课的内容可能会有一个感觉,代码的架构不是很好。不好在什么地方呢?我来看下上节课的代码:
  1. using System;
  2. delegate void EatDelegate(string food);
  3. class MyDelegate
  4.     static void zsEat(string food)
  5.     {
  6.         Console.WriteLine("张三吃" + food);
  7.     }
  8.     static void lsEat(string food)
  9.     {
  10.         Console.WriteLine("李四吃" + food);
  11.     }
  12.     static void wwEat(string food)
  13.     {
  14.         Console.WriteLine("王五吃" + food);
  15.     }
  16.     static void Main()
  17.     {
  18.         EatDelegate zs = new EatDelegate(zsEat);
  19.         EatDelegate ls = new EatDelegate(lsEat);
  20.         EatDelegate ww = new EatDelegate(wwEat);
  21.         //声明一个委托链,不需要实例化
  22.         EatDelegate eatChain;
  23.         //张三李四王五刚刚放假,非常高兴决定搞一个party
  24.         Console.WriteLine("张三,李四,王五开座谈会");
  25.         //他们三个人都在吃西瓜呀
  26.         eatChain = zs + ls + ww;
  27.         eatChain("西瓜");
  28.         //这个时候,李四的电话响了
  29.         Console.WriteLine("李四出去接电话");
  30.         //李四就吃不了西瓜了
  31.         eatChain -= ls;
  32.         //张三和王五继续吃香蕉
  33.         eatChain("香蕉");
  34.         //过了一会李四回来了
  35.         Console.WriteLine("李四回来了");
  36.         eatChain += ls;
  37.         //他们接着吃桔子
  38.         eatChain("桔子");
  39.     }
  40. }
张三李四王五在吃东西,这时候如果马六陈七也加入进来吃东西,我们按照上面的逻辑就必须再写2个静态方法。如果有10个人吃东西,那么我们就要增加10个静态方法。如果100个人吃东西,就要...这样的代码很明显非常的不合理。这时候我们就可以考虑对这些方法进行一些包装,通过观察每个方法都有两个共同点,第一他们都有共同的属性名字,第二他们在吃一样东西就是food参数。这样我们就可以把这些属性和方法包装到一个类里面,进行动态的调用。   
  1. using System;
  2. delegate void EatDelegate(string food);
  3. //Man
  4. class Man
  5. {
  6.     //字段名是私有属性 name
  7.     private string name;
  8.     //声明一个构造函数
  9.     //构造函数Man带了一个字符串类型的参数name
  10.     //它的功能就是字段name赋值,也就是在创建Man对象的时候对上面私有字段name进行初始化
  11.     public Man(string name)
  12.     {
  13.         this.name = name;
  14.     }
  15.     //这时候每个人都有了自己的名字
  16.     //吃这个动作方法
  17.     public void eat(string food)
  18.     {
  19.         Console.WriteLine(name + "吃" + food);
  20.     }
  21. }
  22. //另外声明一个类Party,作用就是开Party
  23. //也就是作为一个入口函数
  24. class Party
  25. {
  26.     static void Main()
  27.     {
  28.         //现在可以动态的创建每个人了
  29.         Man ZS = new Man("张三");
  30.         Man LS = new Man("李四");
  31.         Man WW = new Man("王五");
  32.         //张三李四王五各自吃的动作加上代理
  33.         EatDelegate zs = new EatDelegate(ZS.eat);
  34.         EatDelegate ls = new EatDelegate(LS.eat);
  35.         EatDelegate ww = new EatDelegate(WW.eat);
  36.         EatDelegate eatChain;
  37.         Console.WriteLine("张三,李四,王五开座谈会");
  38.         eatChain = zs + ls + ww;
  39.         eatChain("西瓜");
  40.         Console.WriteLine("李四出去接电话");
  41.         eatChain -= ls;
  42.         eatChain("香蕉");
  43.         Console.WriteLine("李四回来了");
  44.         eatChain += ls;
  45.         eatChain("桔子");
  46.     }
  47. }
运行后我们看,这一次得出的结果跟上节课的是一模一样的,而我们这节课只是对程序的架构改了一下。刚才我们演示了如何代理一个动态的方法,我们接着往下讲。
  其实我们可以这样去理解位委托,比如说我们在讲可不可以把一个方法做为另一个方法的参数进行传递呢?这样做可以带来很多的好处,而代理呢就可以实现这个功能。代理,本身就是一个对象,他可以作为一个方法的参数进行传递。下面我们就来演示如何把委托作为一个方法的参数进行传递。
  这回我们倒回来,首先呢想像一下这个方法是如何调用的,然后呢回过头来再来实现这个方法。
  1. using System;
  2. delegate void EatDelegate(string food);
  3. //Man
  4. class Man
  5. {
  6.     private string name;
  7.     public Man(string name)
  8.     {
  9.         this.name = name;
  10.     }
  11.     public void eat(string food)
  12.     {
  13.         Console.WriteLine(name + "吃" + food);
  14.     }
  15. }
  16. class Party
  17. {
  18.     //eatToghter可变参数数量方法
  19.     static void eatToghter(string food, params EatDelegate[] values)
  20.     { 
  21.         //首先判断委托数组是否为空
  22.         if (values == null)
  23.         {
  24.             //没人吃东西party结束
  25.             Console.WriteLine("座谈会结束");
  26.         }
  27.         else
  28.         { 
  29.             //首先声明一个委托链并初始化为null
  30.             EatDelegate eatChain = null;
  31.             //用foreach给委托赋值
  32.             foreach (EatDelegate ed in values)
  33.                 eatChain += ed;
  34.             eatChain(food);
  35.             //输入一个空行
  36.             Console.WriteLine();
  37.         }
  38.     }
  39.     static void Main()
  40.     {
  41.         Man ZS = new Man("张三");
  42.         Man LS = new Man("李四");
  43.         Man WW = new Man("王五");
  44.         EatDelegate zs = new EatDelegate(ZS.eat);
  45.         EatDelegate ls = new EatDelegate(LS.eat);
  46.         EatDelegate ww = new EatDelegate(WW.eat);
  47.         //我们设想的就是下面eatToghter方法
  48.         //这回我们所实现的是可变参数数量的这么一个方法
  49.         //在前面的讲座方法2中我们曾经介绍过如何实现可变参数数量的方法
  50.         //接下来我们在上面去实现这个方法
  51.         Console.WriteLine("张三,李四,王五开座谈会");
  52.         eatToghter("西瓜",zs,ls,ww);
  53.         Console.WriteLine("李四出去接电话");
  54.         eatToghter("香蕉", zs, ww);
  55.         Console.WriteLine("李四回来了");
  56.         eatToghter("桔子", zs, ls, ww);
  57.         //座谈会结束
  58.         eatToghter(null,null);
  59.     }
  60. }
编译执行,效果如下:

  这里我们演示了如何把委托作为一个方法的参数进行传递,并对它进行动态的调用。
  如果大家对委托要有一个深入的了解请访问MSDN网站的WebCast网络讲座,其中余晖老师有一个《Modern C#系列课程》,他的最后一讲是《深入委托和事件》,大家可以下载进行观看学习。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值