C#委托(一)——说明及举例

C#命名空间下有五种类型,分别为:

类、构造、接口、枚举、委托。

委托被定义为5中基本类型的一种,也就意味着代码可以这么写:

using System;

namespace Test
{
    delegate void PrintAny();
    class Program
    {
        public PrintAny handler;

        void PrintNumber()
        {
            Console.WriteLine("1,2,3");
        }
        static void Main(string[] args)
        {
            Program test_01 = new Program();
            test_01.handler = test_01.PrintNumber;
            test_01.handler();
            Console.Read();
        }
    }
}

简单的测试后,可以看到输出结果被打印出来。

接下来我来进一步说明什么是委托。

第一步:委托的定义

百度的定义是——

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。

可以提取三个关键字:类、类型、传递方法

类和类型都有了解,那么就来研究一下传递方法。

1-1、传递方法

一般编写代码的时候都是函数中传递各种参数,可以是数值类型可以是对象类型;但是牵涉到需要对不同的代码段进行选择可能需要写出长长的if..elseif..else 的选择语句。

 举例说明

例如以下需求:

输入:姓名、国籍   输出:打招呼的方式。

分析:不同国家的人打招呼的方式是不一样的,中国说“吃了吗”、英国说“Hello”。

一般的代码如下——

    class GreetPeople
    {
        string Name;
        string Country;

        public GreetPeople(string name, string Country)
        {
            Name = name;
        }
        public void Greeting()
        {
            if (Country == "Enghlish")
            {
                EnglishGreeting();
            }
            else if (Country == "Chinese")
            {
                ChineseGreeting();
            }
        }

        public void EnglishGreeting()
        {
            Console.WriteLine(Name);
            Console.WriteLine("Hello");
        }

        public void ChineseGreeting()
        {
            Console.WriteLine(Name);
            Console.WriteLine("吃了吗");
        }

        static void Main()
        {
            GreetPeople LiLei = new GreetPeople("LiLei", "English");
            LiLei.Greeting();
            Console.Read();
        }
    }
}

需求发生变更:

现在软件将在20个不同语言的国家地区发布,现在请你对上面的代码进行修改。你会发现你不仅仅要添加函数,同时不得不对Greeting

进行修改,长长的if-else if-else语句一向是不可靠的;调试20个国家的Geeeting函数将是一种折磨!!

现在引入委托,代码如下:

 

 delegate void GreetingHandler();
    class GreetPeople
    {
        string Name;
        string Country;

        public GreetPeople(string name, string Country)
        {
            Name = name;
        }
        public void Greeting(GreetingHandler handler)
        {
            handler();
        }

        public void EnglishGreeting()
        {
            Console.WriteLine(Name);
            Console.WriteLine("Hello");
        }

        public void ChineseGreeting()
        {
            Console.WriteLine(Name);
            Console.WriteLine("吃了吗");
        }

        static void Main()
        {
            GreetPeople LiLei = new GreetPeople("LiLei", "English");
            LiLei.Greeting(LiLei.EnglishGreeting);
            Console.Read();
        }
    }

这个时候Greeting函数仅仅作为函数的触发器,选择是在Main第二行决定的作为构造函数的参数“English”并没有提供有价值的信息。这里存在风险就是国家不容易写错但是调用的函数很可能不对。

代码稍微修改了一下:

    delegate void GreetingHandler();
    class GreetPeople
    {
        string Name;
        string Country;

        private static Dictionary<string, GreetingHandler> CountryDic = new Dictionary<string, GreetingHandler>();

        static GreetPeople()
        {
            CountryDic.Add("English", EnglishGreeting);
            CountryDic.Add("Chinese", ChineseGreeting);
        }

        public GreetPeople(string name, string country)
        {
            Name = name;
            Country = country;
        }
        public void Greeting()
        {
            GreetingHandler handler;

            Console.WriteLine(Name);
            if (CountryDic.TryGetValue(Country, out handler))
            {
                handler();
            }
            else
            {
                Console.WriteLine("未在该国发行!!");
            }
            Console.WriteLine();
        }

        public static void EnglishGreeting()
        {
            Console.WriteLine("Hello");
        }

        public static void ChineseGreeting()
        {
            Console.WriteLine("吃了吗");
        }

        static void Main()
        {
            GreetPeople LiLei = new GreetPeople("LiLei", "English");
            GreetPeople FeiFei = new GreetPeople("FeiFei", "Africa");
            LiLei.Greeting();
            FeiFei.Greeting();
            Console.Read();
        }
    }
}

加了个字典将国家直接映射到对应的调用函数,调用Greeting的时候直接查字典调用即可。可以说,基本实现需求。

1-2、多播委托

现在需求又变了:

软件卖的好将在多国会议展出,要求一次性给所有来宾打招呼;这个时候怎么办?

这就使用到了多播委托了;多播委托一次调用通知多个函数执行,代码如下修改:

 delegate void GreetingHandler();
    class GreetPeople
    {
        string Name;
        string Country;

        private static Dictionary<string, GreetingHandler> CountryDic = new Dictionary<string, GreetingHandler>();

        static GreetPeople()
        {
            CountryDic.Add("English", EnglishGreeting);
            CountryDic.Add("Chinese", ChineseGreeting);
        }

        public GreetPeople(string name, string country)
        {
            Name = name;
            Country = country;
        }
        public void Greeting()
        {
            GreetingHandler handler;

            Console.WriteLine(Name);

            if (Country == "All")
            {
                List<GreetingHandler> tempList = new List<GreetingHandler>(CountryDic.Values);
                if (tempList != null && tempList.Count > 0)
                {
                    handler = tempList[0];
                    for (int i = 1; i < tempList.Count; i++)
                    {
                        handler += tempList[i];
                    }
                    handler();
                }
            }
            else if (CountryDic.TryGetValue(Country, out handler))
            {
                handler();
            }
            else
            {
                Console.WriteLine("未在该国发行!!");
            }
            Console.WriteLine();
        }

        public static void EnglishGreeting()
        {
            Console.WriteLine("Hello");
        }

        public static void ChineseGreeting()
        {
            Console.WriteLine("吃了吗");
        }

        static void Main()
        {
            GreetPeople LiLei = new GreetPeople("LiLei", "English");
            GreetPeople FeiFei = new GreetPeople("FeiFei", "Africa");
            GreetPeople LeiJun = new GreetPeople("LeiJun", "All");

            LiLei.Greeting();
            FeiFei.Greeting();
            LeiJun.Greeting();
            Console.Read();
        }
    }

  

时间: 2024-12-15 14:25:31

C#委托(一)——说明及举例的相关文章

关于C# 委托(delegate)与事件(event)的用法及事例

C#中的委托和事件对于新手可能会有一点难理解,所以先从一个小例子入手,以便能更好的理解其如何使用.有一个学生每天定闹钟在早上6点起床,所以当每天早上6点的时候,闹钟就会响起来,从而学生才会按时起床. 上面例子实际上包括2个类,一个是学生类(Student),一个是闹钟类(Ring).此时,让我们仔细想想,当闹钟到点后如何通知学生呢?当然不要说,闹钟响了,学生能听到这样的话23333,现在是写程序,一切用程序说话.也就是说当时间到了,闹钟类里应该有个给学生发消息的方法(OnSendMessage(

C#委托举例

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace _000控制台练习 8 { 9 //声明委托,写在类外面,命名空间内 10 public delegate void delSay(string name); 11 class Program 12 { 13 stati

c#编程:委托程序举例

委托不是方法,它是一种特殊的类型,用于对与该委托有相同签名(签名这里指方法的参数列表)的方法的调用. 委托的一个重要特点是:委托在调用方法时,不必关心方法所属的对象的类型,它只要求所提供的方法的签名和委托的签名相匹配. 委托声明格式:修饰符 delegate 返回类型 委托名(参数列表) public  delegate  void       BTEvent(); 附一个例子: using System; using System.Collections.Generic; using Syst

javascript举例介绍事件委托的典型使用场景

在了解什么是DOM事件以及给DOM事件绑定监听器的几种方法后,我们来谈谈事件委托. 1. e.target 和 e.currentTarget 当我们给目标元素target 绑定一个事件监听器target.addEventListener(event,function(){}), 并指定回调函数function(e), 函数的参数e表示事件.此时e.target 与 e.currentTarget分别表示自己触发事件的元素与被监听的元素 <html> <body> <ul s

JS事件委托机制简介

目的--为了减少对DOM的操作,使用事件委托. 理解--举例说明:有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三个人在公司门口等快递:二是委托给前台MM代为签收.现实当中,我们大都采用委托的方案(公司也不会容忍那么多员工站在门口就为了等快递).前台MM收到快递后,她会判断收件人是谁,然后按照收件人的要求签收,甚至代为付款.这种方案还有一个优势,那就是即使公司里来了新员工(不管多少),前台MM也会在收到寄给新员工的快递后核实并代为签收. 原理--事件委托是利用事件的冒泡原理来实现的

12-14面向对象--抽象基类、接口、委托

一.抽象类与抽象方法 1.在一个类前面加上abstract关键字,此类就成为了抽象类. 1)当一个类变成抽象类时,就不能作为一个对象使用了,也就是说不能创建新对象,不能new初始化. 2)抽象方法只是一个方法,不能写方法. 3)当一个类继承的是抽象类时,必须要把抽象类的抽象方法重写(override)才可以实现方法. 4)抽象方法必须放在抽象类里面才能使用,抽象方法是在抽象子类中实现的,也就是说抽象子类实现抽象父类所有的抽象方法. 5)有抽象方法的一定是抽象类:有抽象类但不一定有抽象方法. 6)

《Inside C#》笔记(十二) 委托与事件

C#的委托与C++的函数指针类似,但委托是类型安全的,意味着指针始终会指向有效的函数.委托的使用主要有两种:回调和事件. 一 将委托作为回调函数 在需要给一个函数传递一个函数指针,随后通过函数指针调用函数时,就可以使用回调函数的方式.回调函数经常用于异步编程,如果被调用的方法执行起来比较费时,就可以把这个方法放在单独在线程执行,同时将函数指针交给回调函数,线程结束时再调用回调函数.这样调用者就不必因等待执行起来费时的方法而被阻塞了. a) 举例,有一个数据库管理类DBManager,这个类追踪所

C# 委托 代理

C# 委托.代理 举例如下 B的show方法绑定到A的show方法,使得A在show时B也show C#中委托代理用法 定义delegate对象类型,如: public delegate void myEventHandler(object sender ,EventArgs e); 其中 sender代表触发事件的本身,EventArgs 是事件参数类 定义事件参数类,这个可以做也可以不做,看需求,如果需要传递一些信息,可以扩展EventArgs 类,如 public myEventArgs

委托,不知道你是否有也这样理解(一)

目录: 什么是委托 委托的作用 委托的本质 委托链 委托链返回值 一.什么是委托? 委托:将符合规则的方法进行包装.装载方法引用的盒子.将方法作为参数传递. class Program { static void Main(string[] args) { StaticDelegateDome(); } //定义没有返回值委托Feedback,需要一个数值类型参数 internal delegate void Feedback(Int32 value); //方法群:静态.静态.实例 priva