委托(一)

一、什么叫做将方法作为方法的参数?

  我在查阅很多关于委托的资料的时候,都会看到这么一句话:将方法作为方法的参数。但是这句话的含义究竟是什么?他存在的意义在哪里呢?

我们先来看一个例子

  首先定义两个方法:GreetPeople和EnglishGreeting,第一个方法用于向某人问好,传进去姓名的参数比如“Celine”,在这个方法中会调用EnglishGreeting的方法,再次传递“Celine”,最后向屏幕输出“Morning,Celine”

public void GreetPeople(string name)
        {
            EnglishGreeting(name);
        }

        public void EnglishGreeting(string name)
        {
            Console.WriteLine("Morning," + name);
        }


这是中国人表示看不懂,不明白什么是Morning,所以,我们又加入了使用中文打招呼的方法

 public void ChineseGreeting(string name)
        {
            Console.WriteLine("Morning," + name);
        }


  加入这个方法后,客户端也要做相应的修改,因为要根据不同的人,来选择不同的打招呼的方法。这是最好使用枚举来定义语言的种类,然后使用switch case带来进行选择。还记得吗?上一篇中,我们讨论过枚举。

        public enum Language { 
            English,Chinese
        }

        public void GreetPeople(string name,Language lang)
        {
            switch(lang){
                case Language.English:
                    EnglishGreeting(name);
                    break;
                case Language.Chinese:
                    ChineseGreeting(name);
                    break;
            }
        }


  这样就实现了中国人也能看懂的“早上好”,如果在来一个日本人怎么办?再添加一个JanpenesGreeting,然后在GreetPeople里边继续加新的选择分支,而且还要修改枚举类,可以说扩展起来非常麻烦,牵一发而动全身。

  好了,饶了一个大圈,我们最初的问题是什么?把方法当做方法的参数,叮!有没有什么灵感闪现~

  让我们再来看看GreetPeople这个方法,参数接收的是两个变量,一个是姓名一个是国家,假如我们让GeetPeople接收一个参数,而这个参数是另外一个方法,例如我们把EnglishGreeting这个方法当做参数传进去,或者如果你想要传ChineseGreeting,也完全可以,这样我们不就可以把switch case给去掉了吗?

  顺着这个思路,我们写出来下边这个方法,MakeGreeting代表各种不同的语言打招呼的方法,***是代表数据类型的替换符,我们姑且写成下边这个样子

  public void GreetPeople(string name,*** MakeGreeting)
        {
            MakeGreeting(name);
        }


  那么问题来了,这个传进去的方法参数MakeGreeting到底是什么参数类型呢??上边这个方法里边已经清楚的去掉了switch case,其实我们也不再需要枚举了,使用枚举只是为了条件选择的方便,当我们传进去MakeGreeting的时候,已经动态的进行了语言的选择


  终于到了委托登场的时候了!我们使用委托来定义MakeGreeting参数所能代表的方法的种类,也就是MakeGreeting参数的类型,下边就是委托的定义,使用delegate关键字

public delegate void GreetingDelegate(string name);


我们再次定义GreetPeople方法

 public void GreetPeople(string name,GreetingDelegate MakeGreeting)
        {
            MakeGreeting(name);
        }

我们在把最初的方法粘过来对比一下

 public void GreetPeople(string name,Language lang)
 {}


委托的位置其实和枚举类型或者string类型处于相同的位置,string和枚举都是一种类型,那么委托也是一种类型吗??但是委托的声明和类完全不同。

实际上,委托在编译的时候确实会被编译成类,因为delegate是一个类,所以在任何可以声明类的地方都可以声明委托

现在让我们看看完整的代码:

namespace 委托DEMO
{
    public delegate void GreetingDelegate(string name);
    class Program
    {

        private static void GreetPeople(string name,GreetingDelegate MakeGreeting)
        {
            MakeGreeting(name);
        }

        private static void EnglishGreeting(string name)
        {
            Console.WriteLine("Morning," + name);
        }

        private static void ChineseGreeting(string name)
        {
            Console.WriteLine("你好," + name);
        }
        static void Main(string[] args)
        {
            GreetPeople("Celine", EnglishGreeting);
            GreetPeople("陈丹", ChineseGreeting);
            Console.ReadKey();
        }
    }
}

这里写图片描述


总结

委托是一个类,它定义了方法的类型,使得可以将方法当做另一个方法的参数来进行传递,这种讲方法动态地赋给参数的做法,可以避免在程序中大量使用IF-ELSE(SWITCH)语句,同时使程序具有更好的扩展性

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值