事件event用于不同模块之间的通讯,本实例中,定义2个class,一个PublisherClass类申明了2个事件,2个方法,调用方法将会触发事件,通过股票代码code或者板块block查询股票信息。另一个SubscriberClass类,定义了一个List<Stock>成员用来保存股票Stock对象,2个方法注册给PublisherClass类对象的事件。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EventDemo
{
class Program
{
static void Main(string[] args)
{
List<Stock> stocks = new List<Stock>()
{
new Stock("002211", "长城科技", 11.1, "消费电子"),
new Stock("300121", "桔子电子", 22.2, "消费电子"),
new Stock("600006", "远东能源", 33.3, "能源板块"),
new Stock("600101", "望城食品", 44.4, "食品板块")
};
// 实例化2个对象
PublisherClass publisher = new PublisherClass();
SubscriberClass subscriber = new SubscriberClass(stocks);
// 事件注册
// 整个流程来看,要使用事件需申明委托、申明事件、注册事件、触发事件4个步骤
publisher.GetInfoFromCodeEvent += subscriber.ReplyToInputCode;
publisher.GetInfoFromBlockEvent += subscriber.ReplyToInputBlock;
// 触发事件,输入代码查询股票信息
publisher.GetInfoFromCode("300121");
// 触发事件,输入板块查询股票信息
publisher.GetInfoFromBlock("消费电子");
Console.ReadLine();
}
}
// 委托申明
public delegate void GetInfoFromCodeEventHandler(string code);
public delegate void GetInfoFromBlockEventHandler(string block);
// 事件发布者
public class PublisherClass
{
// 事件申明,事件类型是委托类型
public event GetInfoFromCodeEventHandler GetInfoFromCodeEvent;
public event GetInfoFromBlockEventHandler GetInfoFromBlockEvent;
public void GetInfoFromCode(string code)
{
GetInfoFromCodeEvent?.Invoke(code);
}
public void GetInfoFromBlock(string block)
{
GetInfoFromBlockEvent?.Invoke(block);
}
}
/// <summary>
/// SubscriberClass订阅者
/// </summary>
public class SubscriberClass
{
private List<Stock> _stocks;
public SubscriberClass(List<Stock> list)
{
_stocks = list;
}
public void ReplyToInputCode(string code)
{
foreach(Stock stock in _stocks)
{
if(stock.code == code)
{
Console.WriteLine("Input stock: {0}\nName : {1}\nPrice : {2}\nBlock : {3}", stock.code, stock.name, stock.price, stock.block);
}
}
}
public void ReplyToInputBlock(string block)
{
Console.WriteLine("------ Input Block : {0} ------", block);
foreach (Stock stock in _stocks)
{
if (stock.block == block)
{
string index = _stocks.IndexOf(stock).ToString();
Console.WriteLine("Index : {0}\nCode : {1}\nName : {2}\nPrice : {3}\n", index, stock.code, stock.name, stock.price);
}
}
}
}
public class Stock
{
public string code;
public string name;
public double price;
public string block; // 板块
public Stock(string _code, string _name, double _price, string _block)
{
code = _code;
name = _name;
price = _price;
block = _block;
}
}
}
如下代码,是在上面例子基础上增加一个AddStock功能。使用了dotnet自带的EventHandler事件代理,以及使用EventArgs类在模块之间传递事件信息。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EventDemo
{
class Program
{
static void Main(string[] args)
{
List<Stock> stocks = new List<Stock>()
{
new Stock("002211", "长城科技", 11.1, "消费电子"),
new Stock("300121", "桔子电子", 22.2, "消费电子"),
new Stock("600006", "远东能源", 33.3, "能源板块"),
new Stock("600101", "望城食品", 44.4, "食品板块")
};
// 实例化2个对象
PublisherClass publisher = new PublisherClass();
SubscriberClass subscriber = new SubscriberClass(stocks);
// 事件注册
// 整个流程来看,要使用事件需申明委托、申明事件、注册事件、触发事件4个步骤
publisher.GetInfoFromCodeEvent += subscriber.ReplyToInputCode;
publisher.GetInfoFromBlockEvent += subscriber.ReplyToInputBlock;
publisher.AddStockEvent += subscriber.ReplyToAddStock;
// 触发事件,输入代码查询股票信息
publisher.GetInfoFromCode("300121");
// 触发事件,输入板块查询股票信息
publisher.GetInfoFromBlock("消费电子");
// 触发事件,给股票列表新增一个Stock
Stock stock = new Stock("300001", "大中华", 55, "国企改革");
publisher.AddStock(stock);
Console.ReadLine();
}
}
// 委托申明
public delegate void GetInfoFromCodeEventHandler(string code);
public delegate void GetInfoFromBlockEventHandler(string block);
// 事件发布者
public class PublisherClass
{
// 事件申明,事件类型是委托类型
public event GetInfoFromCodeEventHandler GetInfoFromCodeEvent;
public event GetInfoFromBlockEventHandler GetInfoFromBlockEvent;
// 事件申明,使用内置EventHandler代理
public event EventHandler<AddStockEventArgs> AddStockEvent;
public void GetInfoFromCode(string code)
{
GetInfoFromCodeEvent?.Invoke(code);
}
public void GetInfoFromBlock(string block)
{
GetInfoFromBlockEvent?.Invoke(block);
}
public void AddStock(Stock stock)
{
AddStockEventArgs args = new AddStockEventArgs();
args.stock = stock;
//OnAddStockEvent(args);
AddStockEvent?.Invoke(this, args);
}
// 也可以把AddStock()方法拆分成如下AddStock()和OnAddStockEvent()方法
// 下面的方式是微软Example中的方式,具体描述可以参考文档
//public void AddStock(Stock stock)
//{
// AddStockEventArgs args = new AddStockEventArgs();
// args.stock = stock;
// OnAddStockEvent(args);
//}
// 为了继承类可以重写该函数,需声明为virtual虚函数,
//protected virtual void OnAddStockEvent(AddStockEventArgs e)
//{
// EventHandler<AddStockEventArgs> handler = AddStockEvent;
// handler(this, e);
//}
}
// 继承EventArgs类,stock成员用于模块间传递
public class AddStockEventArgs : EventArgs
{
public Stock stock;
}
/// <summary>
/// SubscriberClass订阅者
/// </summary>
public class SubscriberClass
{
private List<Stock> _stocks;
public SubscriberClass(List<Stock> list)
{
_stocks = list;
}
public void ReplyToInputCode(string code)
{
foreach(Stock stock in _stocks)
{
if(stock.code == code)
{
Console.WriteLine("Input stock: {0}\nName : {1}\nPrice : {2}\nBlock : {3}", stock.code, stock.name, stock.price, stock.block);
}
}
}
public void ReplyToInputBlock(string block)
{
Console.WriteLine("------ Input Block : {0} ------", block);
foreach (Stock stock in _stocks)
{
if (stock.block == block)
{
string index = _stocks.IndexOf(stock).ToString();
Console.WriteLine("Index : {0}\nCode : {1}\nName : {2}\nPrice : {3}\n", index, stock.code, stock.name, stock.price);
}
}
}
public void ReplyToAddStock(object sender, AddStockEventArgs e)
{
_stocks.Add(e.stock);
Console.WriteLine("------ 增加一条股票信息 从新显示 ------");
Console.WriteLine("------ Stock List ------");
foreach (Stock stock in _stocks)
{
string index = _stocks.IndexOf(stock).ToString();
Console.WriteLine("Index : {0}\nCode : {1}\nName : {2}\nPrice : {3}\nBlock : {4}\n", index, stock.code, stock.name, stock.price, stock.block);
}
}
}
public class Stock
{
public string code;
public string name;
public double price;
public string block; // 板块
public Stock(string _code, string _name, double _price, string _block)
{
code = _code;
name = _name;
price = _price;
block = _block;
}
}
}
参考文档:
https://docs.microsoft.com/en-us/dotnet/standard/events/
https://docs.microsoft.com/en-us/dotnet/api/system.eventhandler?view=net-6.0
https://docs.microsoft.com/en-us/dotnet/api/system.eventargs?view=net-6.0
https://blog.csdn.net/qq_27278957/article/details/86627861