使用事件
定义和发布事件
事件是建立在委托的基础上的,当某类发生某一事情后,可以通过事件机制通知已经注册的类或对象正在发生的事情,然后这些类或对象做出响应。
事件的本质是委托,但它通常是特定的函数类型,可以将事件理解为委托变量,订阅事件就是为委托变量赋值,同样也是使用“+=”/“-=”。
在定义事件之前要先定义委托,只不过这个委托是特定的函数类型,它没有返回值,并且具有两个参数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);
}
}
}
}
}