C# 关于事件的一些心得

使用事件

定义和发布事件

    事件是建立在委托的基础上的,当某类发生某一事情后,可以通过事件机制通知已经注册的类或对象正在发生的事情,然后这些类或对象做出响应。

    事件的本质是委托,但它通常是特定的函数类型,可以将事件理解为委托变量,订阅事件就是为委托变量赋值,同样也是使用“+=”/“-=”。

    在定义事件之前要先定义委托,只不过这个委托是特定的函数类型,它没有返回值,并且具有两个参数sender和arg。

例如:

Public delegate void PriceChangedEventHandler(object sender,PriceChangedEventAgrs arg);

    为什么会这样呢?这是因为在.Net 框架中,事件是基于EventHandler委托和EventArgs基类的。

    在看上面的例子中的两个参数,一个是object类型的sender,表示事件的发起者,一个是PriceChangedEventArgs 类型的arg,表示事件参数,通常是由EventArgs类派生出来的,所以,在定义一个事件之前,通常先定义一个参数类,派生自EventArgs,该类包含了事件发起者需要传递给事件订阅者的全部信息。

    定义好委托之后,需要定义一个事件,可以理解为定义一个委托变量,只不过不是直接定义,需要加上“event”关键字,来说明这是一个事件,不过可以理解为就是一个委托变量。

例如:

Public event PricechangedEventHandler PriceChanged;

    接下来就是引发事件,可以理解为使用委托变量,引发事件通常放在一个名为OnXXXX()的函数中,这样在在其他地方调用该函数时,就引发事件,即使用委托变量,调用相应的函数(事件处理程序)。

订阅和处理事件

    订阅,实际上就是将函数添加到委托变量的函数列表中,在这里,就是将事件处理程序添加到事件的列表中。

    处理事件,就是委托变量调用的函数,即事件发生后调用事件处理程序。

 

例子

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace EventApp

{

    class Program

    {

        /// <summary>

        /// 实现用户订阅事件,也就是为委托变量赋值,通过+=。。。

        /// </summary>

        /// <param name="args"></param>

        static void Main(string[] args)

        {

            //定义两个shop对象,用来引发事件

            Shop shop1 = new Shop("Shop1");

            Shop shop2 = new Shop("Shop2");

 

            //定义两个customer对象,用来订阅事件并处理事件

            Customer cust1 = new Customer("Customer1");

            Customer cust2 = new Customer("Customer2");

 

            //cust1订阅shop1的pricechanged事件

            shop1.PriceChanged += cust1.Shop_PriceChanged;

 

            //引发事件

            Console.WriteLine("1. shop1.UpdatePrice(\"Goods1\",2.2f)......");

            shop1.UpdatePrice("Goods1", 2.2f);

 

            //cust2订阅shop2的pricechanged事件

            shop2.PriceChanged += cust2.Shop_PriceChanged;

 

            //引发事件

            Console.WriteLine("2. shop2.UpdatePrice(\"Goods2\",3.4f),......");

            shop2.UpdatePrice("Goods2", 3.4f);

 

            //cust2订阅shop1的pricechanged事件

            shop1.PriceChanged += cust2.Shop_PriceChanged;

 

            //引发事件

            Console.WriteLine("3. shop1.UpdatePrice(\"Goods3\",55.2f)......");

            shop1.UpdatePrice("Goods3", 55.2f);

 

            //cust1取消shop1的pricechanged事件

            shop1.PriceChanged -= cust1.Shop_PriceChanged;

 

            //引发事件

            Console.WriteLine("4. shop1.UpdatePrice(\"Goods4\",9.2f)......");

            shop1.UpdatePrice("Goods4", 9.2f);

 

            Console.ReadLine();

 

 

        }

        /// <summary>

        /// 商品价格变化发生时的事件参数

        /// </summary>

        public class PriceChangedEventArgs:EventArgs

        {

            private string str_Name;

            public string Str_Name

            {

                get { return this.str_Name; }

            }

            private float flo_Price;

            public float Flo_Price

            {

                get { return this.flo_Price; }

            }

            public PriceChangedEventArgs(string name,float newprice)

            {

                this.str_Name = name;

                this.flo_Price = newprice;

            }

        }

        /// <summary>

        /// 定义委托

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="arg"></param>

        public delegate void PriceChangedEventHandler(object sender, PriceChangedEventArgs arg);

        public class Shop

        {

            private string shopname;

            /// <summary>

            /// 属性

            /// </summary>

            public string ShopName

            {

                get { return this.shopname; }

            }

            /// <summary>

            /// 构造函数

            /// </summary>

            /// <param name="spname"></param>

            public Shop(string spname)

            {

                this.shopname = spname;

            }

            public event PriceChangedEventHandler PriceChanged;       //相当于声明委托变量,这里通过event关键字将其称为事件

            /// <summary>

            /// 引发事件的函数

            /// </summary>

            /// <param name="arg"></param>

            protected void OnPriceChanged(PriceChangedEventArgs arg)

            {

                if (this.PriceChanged!=null)

                {

                    PriceChanged(this, arg);                      //相当于使用委托变量,这里只不过将使用委托变量放在了一个函数里,整体成为引发事件,实质就是使用委托变量。

                }

            }

            public void UpdatePrice(string nm,float nprice)

            {

                PriceChangedEventArgs arg = new PriceChangedEventArgs(nm, nprice);

                this.OnPriceChanged(arg);

            }

         

        }

        /// <summary>

        /// 客户信息,订阅事件

        /// </summary>

        public class Customer

        {

            private string name;

            public string _Name

            {

                get { return this.name; }

            }

            public Customer(string nm)

            {

                this.name = nm;

            }

            /// <summary>

            /// PriceChanged事件处理函数

            /// </summary>

            /// <param name="sender"></param>

            /// <param name="arg"></param>

            public void Shop_PriceChanged(object sender, PriceChangedEventArgs arg)

            {

                Shop sp = sender as Shop;

                if (sp != null)

                {

                    Console.WriteLine("{0}收到{1}:{2}新价格为{3}¥", this._Name, sp.ShopName, arg.Str_Name, arg.Flo_Price);

                }

            }

        }

    }

}

 

C# 关于事件的一些心得

上一篇:(转)C#中的委托,匿名方法和Lambda表达式


下一篇:简单方便的堡垒机自动登录脚本