zoukankan      html  css  js  c++  java
  • 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();
            }
        }
    }

    这个是有参数的事件。

  • 相关阅读:
    day23 笔记
    iframe子页面与父页面通信
    js格式化时间
    自定义滚动条样式
    表格隔行换色
    css除第一个子元素的其他子元素的4种方法,超实用!
    子div在父div里居中
    红橙黄绿蓝靛紫-RGB-十六进制
    阿里巴巴矢量图标库 字体图标的下载与使用
    calc属性不生效
  • 原文地址:https://www.cnblogs.com/yumaster/p/5352523.html
Copyright © 2011-2022 走看看