C#中的委托和事件

1.委托

委托的声明原型是 
delegate <函数返回类型> <委托名> (<函数参数>)
例如:public delegate void Calculator(int i, int j);
这样就定义了一个委托,但是委托在.net内相当于声明了一个类,类如果不实例化为对象,很多功能是没有办法使用的,委托也是如此.

下面,直接来定义一个委托,并且来使用委托。

namespace _delegate
{
    public delegate void Calculator(int i, int j);//定义委托Compute,两个参数i和j;方法签名和加减法一样。无非是多加了一个delegate关键字。
    public class DelegateCal
    {
        private static void Add(int i, int j)//声明加法
        {
            Console.WriteLine("{0}", i + j);
        }
        private static void Sub(int i, int j)//声明减法
        {
            Console.WriteLine("{0}", i - j);
        }
        private static void Calculator(int i, int j, Calculator Cal)//Calculator这个方法有三个参数,第三个Compute是之前定义的委托类型。
        {
            Cal(i, j);  //委托类型Compute定义的一个Cal变量。在给Cal赋值的时候动态地决定使用哪个方法
        }
        //委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。
        /*static void Main(string[] args)
        {
            Calculator(2, 5, Add);
            Calculator(5, 2, Sub);
            Console.ReadLine();
        }*/
        //从此可以看出Compute和int都是数据类型,那么是不是可以定义两个变量,把方法赋给变量。  
        static void Main(string[] args)
        {
            //将方法绑定到委托
            /*Compute delegate1, delegate2;
            delegate1 = Add;
            delegate2 = Sub;
            Calculator(1,2, delegate1);//3
            Calculator(7,4, delegate2);//3
            Console.ReadLine();
           */
            //其实,委托还有一个特性不同于int或其他数据类型,它可以将多个方法绑定到同一个委托上。如下:
            /*Compute delegate1;
            delegate1 = Add;
            delegate1 += Sub;
            Calculator(5, 1, delegate1);
            Console.ReadLine();  //先输出加法为6,后输出减法为4;
             */
            //其实,我们可以不用Calculator方法,通过委托来直接调用Add方法或者Sub方法。如下:
            Calculator delegate1;
            delegate1 = Add;
            delegate1 += Sub;
            delegate1(9, 2);
            Console.ReadLine();//和为11、差为7
        }
    }
}

2.事件

了解了委托之后,咱们来讲一下事件。
C#中事件的定义和委托的声明其实是非常的相似:
                   event <委托类型> 事件名
例如: public event Computer OnComputer;//定义事件,将其与代理绑定
声明了事件之后就可以实例化这个事件,注册函数到事件中。
下面咱用一个例子来说明:

namespace _delegate
{
    public delegate void Computer(); //首先声明一个委托。
    public class EventCal
    {
        public event Computer OnComputer;//定义事件,将其与代理绑定
        public virtual void FireEvent()//触发事件的方法
        {
            if (OnComputer != null)
            {
                OnComputer();  //触发事件
            }
        }
    }
    public class Compere  //主持人
    {
        public void EventHandler()//事件处理函数
        {
            int a = 1;
            int b = 1;
            int c = a + b;
            Console.WriteLine("a+b={0}",c);
        }
        public static void Main()
        {
            EventCal ec = new EventCal();
            Compere c = new Compere();
            ec.OnComputer += new Computer(c.EventHandler);//注册
            ec.FireEvent();
            Console.Read();
        }
    }
}

EventCal类相当于一个时间发布者,它定义了事件的相关信息,包括定义了一个事件用于计算(OnComputer),以及一个触发事件的函数(FireEvent())

Compere类则相当于一个事件订阅者,或者说叫做主持人吧。它定义了一个事件处理函数(EventHandle()),并用+=将其与事件联系起来。从而使事件触发的时候能够调用我这个方法,其实就是计算一下a+b的值。
注意:事件处理函数的方法签名要与代理的方法签名相同,这是非常重要的一点

namespace _delegate
{
    public delegate void Computer(object sender, MyEventArgs e);//sender 产生事件的对象,e 事件的参数
    public class EventCal
    {
        public event Computer OnComputer;//定义事件,将其与代理绑定
        public virtual void FireEvent(MyEventArgs e)//触发事件的方法
        {
            if (OnComputer != null)
            {
                OnComputer(this,e);  //触发事件
            }
        }
    }
    public class MyEventArgs : EventArgs//定义事件参数类
    {
        public readonly int _a,_b;
        public MyEventArgs(int a,int b)//这是一个构造函数,参数列表为int a,int b
        {
            this._a = a;
            this._b = b;
        }
    }
    public class Compere  //主持人
    {
        public void EventHandler(object sender,MyEventArgs e)//事件处理函数
        {
            Console.WriteLine("a+b={0}",e._a+e._b);
        }
        public static void Main()
        {
            EventCal ec = new EventCal();
            Compere c = new Compere();
            MyEventArgs e = new MyEventArgs(1, 1); //构造函数传参
            ec.OnComputer += new Computer(c.EventHandler);//注册
            ec.FireEvent(e);
            Console.Read();
        }
    }
}

这个是有参数的事件。

posted @ 2016-04-04 18:17  土伦  阅读(295)  评论(0编辑  收藏  举报