C#——委托

因为评教的维护工作,有一个星期计算机进度没有动,觉得还是时间管理出了问题,计划的总结也没有完成,现在就以这篇关于委托和事件的总结作为快速进入学习状态的调和剂吧。


定义和由来

委托是一种引用方法的类型,一旦为委托分配了方法,委托将于该方法具有完全相同的行为

因为是初学者对于委托的概念不是很理解,就查阅了很多资料,都说委托很类似于C中的指针,当然C中指针的功能有一些诟病,C# 想要拥有指针强大的功能,但是又要摒弃那些诟病,所以委托就出现了。我们可以把委托看成是一个升级的指针,因为函数指针只能简单的把地址指向另一个函数,而委托不仅仅能把地址指向另一个函数,而且还能传递参数,返回值等多个信息


如何声明和创建委托



using System.Threading.Tasks;

namespace 委托
{
    public delegate void DelegateClass();// 声明委托
    class Program
    {
        public static void Fangfa1()
        { }

        static void Main(string[] args)
        {
            DelegateClass dc1 = new DelegateClass(Program.Fangfa1);//方法一,方法有new关键字,参数为类.方法名
            DelegateClass dc2 = new DelegateClass(Fangfa1);//方法二,常用格式,有new关键字,参数为方法
            DelegateClass dc3 = Fangfa1;//方法三,不需要new关键字,直接加上方法名

            Fangfa2 ac = new Fangfa2();//方法四,实例化一个对象,然后用对象名.方法名
            DelegateClass de4 = new DelegateClass(ac.Fangfa二);
        }
    }
}

namespace 委托
{
    class Fangfa2
    {
        public void Fangfa二()
        { }
    }
}


一个小例子

namespace 委托2
{
    class Program
    {
        delegate string MyDelegate();//声明委托
        static void Main(string[] args)
        {
            string str = "";
            MyDelegate myreadline = new MyDelegate(Console.ReadLine);//委托实例化,让其引用Console.ReadLine的方法

            Console.WriteLine("请输入字符串");
            str = myreadline();
            Console.WriteLine("你输入的字符串是{0}", str);
            Console.ReadLine();

        }
    }
}



可以看出,实例化出来的委托对象myreadline通过引用Console.ReadLine的方法,实现了Console.ReadLine的功能。


自己理解的委托

在百度百科查委托时发现了一个小例子,很好的说明了委托的作用,下面简单总结一下这个小例子
定义两个简单的方法,一个是想某人问好的方法,一个是问好的方法:

namespace 委托2
{
    class Greet
    {
        public void GreetPeople(string name)//调用问好的方法,传入参数是姓名姓名
        {
            EnglishGreeting(name);
        }

        public void EnglishGreeting(string name)//问好的方法
        {
            Console.WriteLine("Morning," + name);
        }
    }
}

但是现在全球一家亲,你用英语问好我们中国人都知道,但是如果你用别的国家的语言问好,我们就不知道你再说什么了,所以这个GreetPeople方法就要扩展出“根据不同国家的人,说不同国家的话”这个功能,这就需要在GreetPeople中添加判断条件,还要新添一种语言的问好方法

 class Greet
    {
        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;
            }
        }

        public void EnglishGreeting(string name)//问好的方法
        {
            Console.WriteLine("Morning," + name);
        }

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

从上边的代码可以看出,这段代码的扩展性很差,违背了开闭原则,每次新添语言,都要打开Greet类,添加新的条件,新的问好方法。

我们看GreetPeople这个方法的声明


 public void GreetPeople(string name,language lang)


string是参数类型,name是变量,碰到谁,我们就赋给他碰到那个人的名字,既然这个方法可以接受参数变量,那么这个变量也可以看成一个方法,当我们给这个变量赋值EnglishGreeting的时候,他代表着EnglishGreeting这个方法,当赋值给他ChineseGreeting时,他就代表着ChineseGreeting这个方法,所以说这个变量可以看做一个有着制造功能的语言库,他可以扩展出成千上百种使用不同语言问好的方法。我们给这个变量起个名字叫MakeGreeting,在调用GreetingPeople这个方法时,我们给MakeGreeting参数赋上值,这时选择和种语言就被封装到了MakeGreeting中,就不需要在做判断了。由于MakeGreeting是一个方法,所以它的使用方法也是和EnglishGreeting一样


改之后的代码:

namespace 委托2
{
    public delegate void GreetingDelegate(string name);//声明委托
    class Greet
    {
        private static void EnglishGreeting(string name)//英语问好的方法
        {
            Console.WriteLine("Morning," + name);
        }

        private static void ChineseGreeting(string name)//中文问好的方法
        {
            Console.WriteLine("早上好," + name);
        }

        private static void GreetPeople(string name ,GreetingDelegate MakeGreeting)
        {                                     //委托定义了MakeGreeting的参数类型
            MakeGreeting(name);
        }
        static void Main(string[] args)
        {
            GreetPeople("Khalil",EnglishGreeting);
            GreetPeople ("方大同",ChineseGreeting );
            Console.ReadKey ();
        }
    }
}


我的理解:委托将一些逻辑判断封装到了方法体中,使得方法可以像参数一样,在调用别的方法的时候,赋值给函数一个已经封装好的方法,这就使得一些本该在调用的这个方法里做的一些逻辑判断,转移到了传参中,传进去的参数已经是经过判断的了,这样使得程序员可以灵活调用响应的方法。

事件

事件构建在委托的基础上。事件是一种信号机制,他在某些操作发生时自动地发出通知。事件定义为对象发送的消息,发信号通知操作的发生。我感觉事件类似于数据库库中的触发器。先设定好如果符合某些操作,则自动发送消息。




评论 38
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值