浅谈C#委托典型应用之自定义事件

事件是什么?比如对于一个按钮,用户点击这个按钮之后程序就会给出反应,这就是事件。那委托是什么呢?委托是当用户点击按钮之后程序将要执行已经编写好的函数,不然怎么给出反应呢。这里说明一下,委托不是函数,但它可以指向一个函数,类似于C中的函数指针。

先简单介绍一下委托的基本用法
(1)委托用关键字delegate声明,有访问权限,返回值,委托名称,参数
(2)定义的委托没有方法体,直接以;结束
(3)以该委托名声明变量
(4)将声明的变量指向方法,注意:声明委托的返回值、参数类型和个数决定该委托只能指向以同样结构声明的函数
(5)调用:

class Program
{
    //声明委托类型
    public delegate int Mydele(int a, int b);

    static void Main(string[] args)
    {
        //定义委托变量
        Mydele d1, d2;
        //为委托变量指向函数
        d1 = new Mydele(sum);
        d2 = new Mydele(muitly);
        Console.WriteLine(deleTest(d1,3,5));
        Console.WriteLine(deleTest(d2, 3, 5));
        Console.Read();
    }

    public static int deleTest(Mydele d,int a,int b)
    {
        return d(a, b);
    }

    public static int sum(int a,int b)
    {
         return a + b;
    }

    public static int muitly(int a,int b)
    {
        return a * b;
    }
}

浅谈C#委托典型应用之自定义事件

通过这个例子不难发现,我们可以将方法作为变量传入函数中,对于接受委托变量的函数来说,它不关心这个委托到底是指向哪个方法的,就本例来说,它知道的就是这个委托指向的方法有一个int类型返回值,有2个int类型参数,函数体里面执行了一次这个委托指向的方法。简单的说就是将函数体里面的某一个功能委托给外部去实现,然后当做参数传进来(这个参数就是声明为delegate的变量)。

接下来看一下事件委托又是什么东西,简单的说就是:事件是委托的封装,委托的指向功能和调用功能由事件负责,在这里委托的作用就是告诉事件,你只能接受我已经定义好结构的函数,如返回值类型,参数类型和个数。看一下例子:

class Program
{
    //声明委托类型
    public delegate int Mydele(int a, int b);
    //声明该委托的事件
    public event Mydele MydeleHandle;
    static void Main(string[] args)
    {
        //这里不再定义委托变量,直接通过其事件进行处理
        MydeleHandle += sum;
        //可以注册多个同结构的函数,但只有最后一个生效
        //MydeleHandle += muitly;
        //调用
        int result=MydeleHandle(3, 5);
        Console.WriteLine(result);
    }
    public static int sum(int a,int b)
    {
        return a + b;
    }

    public static int muitly(int a,int b)
    {
        return a * b;
    }
}

浅谈C#委托典型应用之自定义事件

最后再看一下自定义事件是怎么回事,注意,这里是才是实际应用,但前面的基础用法同样很重要,定义一个测试类:

class DelegateTest
{
    private int xPoint;//X坐标
    private int yPoint;//Y坐标

    public delegate void XPointChangeDele(int x,int y);
    public delegate void YPointChangeDele(int x,int y);

    public event XPointChangeDele XChangeHandle;
    public event YPointChangeDele YChangeHandle;

    public int XPoint
    {
        get { return xPoint; }
        set
        {
            xPoint = value;
            /*
             * 这里是重点,当x轴发生变化会执行以下event接收的用户自定义函数,
             * 需要考虑若用户没有注册该事件的话这里是null,鲁莽调用会出现空
             * 指针异常,所以设计的时候要考虑周到些,下同
             */
            XChangeHandle?.Invoke(xPoint, yPoint);
        }
    }
    public int YPoint
    {
        get { return yPoint; }
        set
        {
            yPoint = value;
            //重点
            YChangeHandle?.Invoke(xPoint,yPoint);
        }
    }
}

测试:

class Program
{
    static void Main(string[] args)
    {
        //初始化
        DelegateTest dt = new DelegateTest();
        //注册事件
        dt.XChangeHandle += XChange;
        dt.YChangeHandle += YChange;
        //测试x轴与y轴变化时是否触发事件
        dt.XPoint = 25;
        dt.YPoint = 30;
            
        Console.Read();
    }
    public static void XChange(int x,int y)
    {
        Console.WriteLine("X轴发生了变化,当前坐标为({0},{1})",x,y);
    }
    public static void YChange(int x,int y)
    {
        Console.WriteLine("Y轴发生了变化,当前坐标为({0},{1})", x, y);
    }
}

浅谈C#委托典型应用之自定义事件