win8 风格网站模板,vi设计模板源文件,黄石有没有做网站的,浙江省建设信息港三类人员证书查询事件模型简述
C#中事件的运行模式为发布订阅模型#xff0c;事件触发者称为发布者#xff0c;事件处理者称为订阅者
事件模型的五个组成部分
事件#xff08;成员#xff09;事件的拥有者#xff08;类/对象#xff09;事件的响应…事件模型简述
C#中事件的运行模式为发布订阅模型事件触发者称为发布者事件处理者称为订阅者
事件模型的五个组成部分
事件成员事件的拥有者类/对象事件的响应者类/对象事件处理器事件处理器的成员方法事件订阅 -
五个组成部分的关系为
事件的拥有者拥有事件事件的响应者订阅事件。当事件被触发后事件的拥有者令事件通知事件的响应者事件的响应者通过事件处理器处理事件
事件示例System.Timers.Timer
System.Timers.Timer是.NET提供的线程不安全的计时器类此处介绍其Elapsed事件
System.Timers.Timer timer new(1000);
// Elapsed事件 通过订阅事件
timer.Elapsed (sender, e)
{Console.WriteLine(System.Timers.Timer);
};
timer.Start();
Thread.Sleep(6000);
// 停止计时器
timer.Dispose();
间隔1S事件就会被触发一次然后被事件处理器处理
事件的完整声明
private static void Main(string[] args)
{Customer customer new();Waiter waiter new();customer.Order waiter.TakeOrder;customer.Think(Cake, Medium);
}public class Customer
{private OrderEventHandler orderEventHandler; // 事件用于接收订阅的委托public event OrderEventHandler Order // 事件{add{orderEventHandler value;}remove{orderEventHandler - value;}}public double Bill { get; set; }public void Think(string dishName, string size){Console.WriteLine(Customer: I need {0} {1}, size, dishName);OnOrder(Cake, Medium);}protected void OnOrder(string dishName, string size){if (orderEventHandler ! null){OrderEventArgs args new();args.DishName dishName;args.Size size;orderEventHandler(this, args);}}
}
public class Waiter
{public void TakeOrder(Customer customer, OrderEventArgs e){Console.WriteLine(I will serve you the dish - {0} {1}, e.Size, e.DishName);double basePrice 10;switch (e.Size){case small:basePrice * 0.5;break;case large:basePrice * 1.5;break;default:break;}customer.Bill basePrice;Console.WriteLine(You need to pay ${0}, customer.Bill);}
}
// 依据.net规范, 类的作用是传递事件信息(EventArgs)时, 需在声明时添加EventArgs后缀, 并实现EventArgs类
public class OrderEventArgs : EventArgs
{public string DishName { get; set; }public string Size { get; set; }
}
// 依据.net规范, 委托的作用是处理事件时, 需要在声明时添加EventHandler后缀
public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
上述代码中事件的五个组成部分customer是事件的拥有者waiter是事件的响应者customer.Order是事件waiter.TakeOrder是事件处理器是事件的订阅。此外orderEventHandler是事件用于接收订阅的委托customer.Think是事件的触发者
需要说明的是
1.依据.net规范类的作用是传递事件信息(EventArgs)时需在声明时添加EventArgs后缀并实现EventArgs类上述代码中的OrderEventArgs类
2.依据.net规范委托的作用是处理事件时需要在声明时添加EventHandler后缀上述代码中的OrderEventHandler委托
事件的简略声明
简略声明
从形式上看事件似乎是字段但实际上不是。事件之于委托类似属性之于字段
事件只能出现在或-操作符左侧但OnOrder函数的if语句中却出现在了!操作符左侧原因是此处为C#语法糖简略声明下无显式的委托字段只能如此。Order(this, args)也是出于同样的原因
public class Customer
{public event OrderEventHandler Order; // 事件public double Bill { get; set; }public void Think(string dishName, string size){Console.WriteLine(Customer: I need {0} {1}, size, dishName);OnOrder(Cake, Medium);}protected void OnOrder(string dishName, string size){if (Order ! null){OrderEventArgs args new();args.DishName dishName;args.Size size;Order(this, args);}}
}
完整声明
public class Customer
{private OrderEventHandler orderEventHandler; // 事件用于接收订阅的委托public event OrderEventHandler Order // 事件{add{orderEventHandler value;}remove{orderEventHandler - value;}}public double Bill { get; set; }public void Think(string dishName, string size){Console.WriteLine(Customer: I need {0} {1}, size, dishName);OnOrder(Cake, Medium);}protected void OnOrder(string dishName, string size){if (orderEventHandler ! null){OrderEventArgs args new();args.DishName dishName;args.Size size;orderEventHandler(this, args);}}
}
实际上大多数情况下可以直接使用C#提供的事件委托EventHandler来声明事件无需自己声明事件委托
但是需要注意EventHandler委托的参数格式是(object? sender, EventArgs e)被委托的函数中需要做里氏转换此即为何自定义的XXXEventArgs类最好派生自EventArgs类的原因
private static void Main(string[] args)
{Customer customer new();Waiter waiter new();customer.Order waiter.TakeOrder;customer.Think(Cake, Medium);
}public class Customer
{public event EventHandler Order;public double Bill { get; set; }public void Think(string dishName, string size){Console.WriteLine(Customer: I need {0} {1}, size, dishName);OnOrder(Cake, Medium);}protected void OnOrder(string dishName, string size){if (Order ! null){OrderEventArgs args new();args.DishName dishName;args.Size size;Order(this, args);}}
}
public class Waiter
{public void TakeOrder(Object customer, EventArgs e){// 里氏转换Customer customer_ customer as Customer;OrderEventArgs e_ e as OrderEventArgs;Console.WriteLine(Waiter: I will serve you the dish - {0} {1}, e_.Size, e_.DishName);double basePrice 10;switch (e_.Size){case Small:basePrice * 0.5;break;case Large:basePrice * 1.5;break;default:break;}customer_.Bill basePrice;Console.WriteLine(Waiter: You need to pay ${0}, customer_.Bill);}
}
// 依据.net规范, 类的作用是传递事件信息(EventArgs)时, 需在声明时添加EventArgs后缀, 并实现EventArgs类
public class OrderEventArgs : EventArgs
{public string DishName { get; set; }public string Size { get; set; }
}
结语
事件基于委托但不等同于委托