第八篇 委托和事件

1 委托

简介:委托(delegate)是一种存储函数的引用类型。委托的声明非常类似于函数,但不带函数体,且要用delegate关键字。委托的声明指定了一个返回类型和一个参数列表。

delegate double ProcessDelegate(double param1,double param2);

定义了委托后,就可以声明该类型的变量。接着把这个变量初始化为与委托具有相同返回类型和参数列表的函数引用。之后,就可以使用委托变量调用这个函数,就像该变量是一个函数一样。

例如,可以把委托变量作为参数传递给一个函数,这样,函数就可以使用委托调用它引用的任何函数,而且在运行之前不必知道调用的是哪个函数。

class Program
{
    delegate dou ble ProcessDelegate(double param1, double param2);

    static double Multiply(double param1, double param2)
    {
        return param1 * param2;
    }

    static double Divide(double param1, double param2)
    {
        return param1 / param2;
    }

    static void Main(string[] args)
    {
        ProcessDelegate process;
        Console.WriteLine("Enter 2 numbers separated with a comma:");
        string input = Console.ReadLine();
        int commaPos = input.IndexOf(',');
        double param1 = Convert.ToDouble(input.Substring(0, commaPos));
        double param2 = Convert.ToDouble(input.Substring(commaPos + 1,input.Length - commaPos - 1));

        Console.WriteLine("Enter M to multiply or D to divide:");
        input = Console.ReadLine();
        if (input == "M")
            process = new ProcessDelegate(Multiply);
        else
            process = new ProcessDelegate(Divide);
        Console.WriteLine("Result: {0}", process(param1, param2));
        Console.ReadKey();
    }
}

注意:要把一个函数引用赋给委托变量,需要使用略显古怪的语法,这个过程比较类似于给数组赋值。必须使用new关键字创建一个委托。在这个关键字后面,指定委托的类型,提供一个引用所需函数的参数。

还可以使用比较简单的语法(但使用长语法更易阅读):

if (input == "M")
    process = Multiply;
else
    process = Divide;

还可以通过参数将委托变量传递给一个函数名(与C++的回调函数类似,但这种方法使用更加方便):

static void ExecuteFunction(ProcessDelegate process)
{
    process(2.2, 3.3);
}

委托主要与事件相结合,才能发挥最大的威力。委托有些类似于C++的函数指针,可以参见下面的链接

http://blog.csdn.net/chenxl929/article/details/75559101

2 事件

先上一段小程序,看个清楚

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Event
{
    class Teacher
    {
        //1 定义委托类型(ProcessWork类似于函数指针)
        public delegate void ProcessWork();
        //2 定义事件(work类似于声明一个ProcessWork类型的函数指针)
        public event ProcessWork work;
        //3 定义引发事件的函数
        /*
         * 类比老师只管布置作业,不管哪些学生去做作业
         * 所以用一个GoToWork()函数去布置作业,让事件去通知订阅了事件的对象
         */
        public void GoToWork()
        {
            work();
        }
    }
    class Student1
    {
        //4 编写事件处理函数
        //类似学生做作业的方法,不管哪个老师布置作业,学生都要做作业
        public void DoHomework()
        {
            Console.WriteLine("1:老师布置作业了!我做完咯");
        }
    }
    class Student2
    {
        //4 编写事件处理函数
        public void DoHomework()
        {
            Console.WriteLine("2:老师布置作业了!我做完咯");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Teacher teac = new Teacher();
            Student1 stud1 = new Student1();
            Student2 stud2 = new Student2();
            //5 订阅事件
            //两个学生都加入老师的微信群
            teac.work += stud1.DoHomework;
            teac.work += stud2.DoHomework;
            //6 引发事件
            //老师在群里布置作业
            teac.GoToWork();
        }
    }
}

运行结果:

事件的详细内容,可以看.NET CLR via C#。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值