本总结是根据刘铁锰视频学习及参考C#图解教程资料整理而来的,个人总结仅供参考
事件与委托的关系
事件是依赖于委托,委托是事件的基础。事件的作用是让对象委托的调用更加的明确和安全,因为事件只能在订阅委托时调用而不能在其他地方引用,这就保证了事件响应者的响应是固定的不能被其他实例随便调用。
事件的实质是委托的包装器,事件的触发必需是事件的拥有者来执行
在声明事件委托时需要注意的格式:(事件的名称)+“EventHandler”,这样增加代码的可读性
同样的在声明事件参数类型时需要在参数类型名称后加“EventArgs”,增加可读性
声明事件的五个要素部分:
1、事件的拥有者--customer1
2、事件的响应者--Waiter1
3、事件--customer1.Order
4、事件的处理器--Waiter1.Action
5、事件的订阅--+=
事件声明完整代码参考
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
/**************************************************主程序调用*******************************************************************/
class program
{
static void Main (string[] args )
{
//声明事件的五个部分:
//1、事件的拥有者--customer1
//2、事件的响应者--Waiter1
//3、事件--customer1.Order
//4、事件的处理器--Waiter1.Action
//5、事件的订阅--+=
//6、事件的触发应该在事件的拥有者里去触发
//代码调用
Customer customer1 = new Customer();
Waiter Waiter1 = new Waiter();
customer1.Order += Waiter1.Action;//>>>事件订阅事件处理器
Console.Read();
customer1.Think();
customer1.PayTheBill();
Console.WriteLine("Mission complete");
Console.ReadKey();//用Console的ReadKey指令用于防止程序执行完自动退出
}
}
//声明事件的子类并添加菜名及规格两个额外参数
public class OrderEventArgs:EventArgs
{
//>>>声明属性时应当先输入prop,然后再敲击两下TAB键会自动声明后面的get,set方法
public string DishName { get; set; }
public string Size { get; set; }
}
//声明委托类型并引用两个输入参数customer和OrderEventArgs
public delegate void OrderEventHandler(Customer Customer, OrderEventArgs e);
/*********************************************************************************************************************/
//声明Customer类
public class Customer
{
//委托字段,用于存储和引用事件处理器(完整声明)
private OrderEventHandler orderEventHandler;
//----------------------------调用委托用于触发及绑定子事件处理器参数-----------------------------------
public void Think()
{
if (this.orderEventHandler != null)
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Potato";
e.Size = "large";
//触发事件用Invoke
this.orderEventHandler.Invoke(this, e);
}
}
//-----------------------------声明事件处理器用于外部订阅事件-----------------------------------
public event OrderEventHandler Order
{
//事件添加器
add
{
//订阅用+=符号表示,value
this.orderEventHandler += value;
}
//事件处理器的移除器
remove
{
this.orderEventHandler -= value;
}
}
//------------------------------------------------------------------------------------------------------------
public double Bill { get; set; }
public void PayTheBill ()
{
Console.WriteLine("I will pay the {0} $",this.Bill);
}
}
/*********************************************************************************************************************/
//声明服务员类
public class Waiter
{
//>>>注意服务员类的Action与委托的输入参数类型是一致的
//当Action与Customer类里委托输入参数致时可以订阅order类事件处理器
public void Action(Customer Customer, OrderEventArgs e)
{
Console.WriteLine("I will serve you the dish.{0}", e.DishName);
double price = 10;
switch (e.Size)
{
case "small":
price *= 0.5;
break;
case "large":
price *= 1.5;
break;
default:
break;
}
Customer.Bill += price;
}
}
}
语法简化
namespace ConsoleApp1
{
/********************************************主程序调用********************************************************/
class program
{
static void Main (string[] args )
{
//声明事件的五个部分:
//1、事件的拥有者--customer1
//2、事件的响应者--Waiter1
//3、事件--customer1.Order
//4、事件的处理器--Waiter1.Action
//5、事件的订阅--+=
//6、事件的触发应该在事件的拥有者里去触发
Customer customer1 = new Customer();
Waiter Waiter1 = new Waiter();
customer1.Order += Waiter1.Action;//<5>事件订阅事件处理器,处理器位于事件响应者中
Console.Read();
customer1.Think();
customer1.PayTheBill();
Console.WriteLine("Mission complete");
Console.ReadKey();
}
}
public class OrderEventArgs:EventArgs
{
//声明属性时应当先输入prop,然后再敲击两下TAB键会自动声明后面的get,set方法
public string DishName { get; set; }
public string Size { get; set; }
}
//委托类型
public delegate void OrderEventHandler(Customer Customer, OrderEventArgs e);
/*********************************************************************************************************************/
//声明Customer类
public class Customer
{
//委托字段,用于存储和引用事件处理器
//private OrderEventHandler orderEventHandler;//1、...委托简略声明可将委托字段省略
//事件声明
//-----------------------------声明事件处理器用于外部订阅事件-----------------------------------
public event OrderEventHandler Order;
//2、...在简略声明里会将事件的添加器与移除器的声明也省略掉
/*
{
//事件添加器
add
{
//订阅用+=符号表示,value
this.orderEventHandler += value;
}
//事件处理器的移除器
remove
{
this.orderEventHandler -= value;
}
}
*/
//------------------------------------------------------------------------------------------------------------
public double Bill { get; set; }
public void PayTheBill ()
{
Console.WriteLine("I will pay the {0} $",this.Bill);
}
//----------------------------调用委托用于触发及绑定子事件处理器参数-----------------------------------
public void Think()
{
Console.WriteLine("I am thinking...");
this.Onorder();
}
//根据方法的单一职责(single responsibility)的原则,一个方法只能完成一个功能,约定事件的触发方法前面需要加On
protected void Onorder()
{
//事件触发完整声明
/*
if (this.orderEventHandler != null)
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Potato";
e.Size = "large";
//触发事件用Invoke
this.orderEventHandler.Invoke(this, e);
}
*/
//3、事件触发简略声明,需要注意的是因为不同于完整声明,简略声明已经将委托字段省略掉所以本应调用字段orderEventHandler在此处
//会报错,此时按照C#的语法糖衣应该用事件order去替换掉orderEventHandler。简而言之,相对于完整声明,简略声明省略掉了委托字段、
//事件的添加器与移除器以及添加语法糖衣将事件order去替换掉事件拥有者customer的委托调用
if (this.Order != null)
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Potato";
e.Size = "large";
//触发事件用Invoke
this.Order.Invoke(this, e);
}
}
}
/*********************************************************************************************************************/
//声明服务员类
public class Waiter
{
public void Action(Customer Customer, OrderEventArgs e)
{
Console.WriteLine("I will serve you the dish.{0}", e.DishName);
double price = 10;
switch (e.Size)
{
case "small":
price *= 0.5;
break;
case "large":
price *= 1.5;
break;
default:
break;
}
Customer.Bill += price;
}
}
}
版权声明:本文为PittDing原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。