用代码来模拟顾客点菜。顾客点菜,服务员处理点菜这个事件。
using System;
using System.Threading;
namespace 事件_完整声明
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
Waiter waiter = new Waiter();
customer.Order += waiter.Action;
customer.Action();//触发这个事件
customer.PayTheBill();
}
}
//事件信息,命名规范:事件名+EventArgs 记住!
//事件信息这个类必须继承自EventArgs,记住就行
public class OrderEventArgs:EventArgs
{
public string DishName { get; set; }
public string Size { get; set; }
}
//委托用来声明事件时
//命名规范:事件名+EventHandler 记住!
public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
public class Customer
{
public OrderEventHandler orderEventHandler;
//声明事件,event是声明事件关键字
public event OrderEventHandler Order
{
add
{
this.orderEventHandler = value;
}
remove
{
this.orderEventHandler = value;
}
}
public double Bill { get; set; }
public void PayTheBill()
{
Console.WriteLine("I will pay ${0}.",this.Bill);
}
//下面几个方法用来触发事件
public void Walkln()//进店
{
Console.WriteLine("Walk into the restaurant.");
}
public void SitDown()//坐下
{
Console.WriteLine("Sit down");
}
public void Think()//思考吃什么
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Let me think...");
Thread.Sleep(1000);
}
if(orderEventHandler!= null)
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Kongpao Chicken";
e.Size = "large";
//触发事件处理器
this.orderEventHandler.Invoke(this, e);
}
}
public void Action() //触发这个事件的方法名 最好为On+事件名=OnOrder
{
Console.ReadLine();
this.Walkln();
this.SitDown();
this.Think();
}
}
public class Waiter
{
internal 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;
}
}
}
事件是基于委托的
1.事件需要用委托类型来做一个约束,这个约束既规定了事件能发送什么消息给响应者,也规定了响应者能收到什么样的事件消息,这就决定了事件响应者的事件处理器必须能够给这个约束匹配上,才能够订阅这个事件。
2.当事件的响应者给事件的拥有者提供了能够匹配这个事件的事件处理器之后,得找个地方把事件处理器保存或者记录下来,能够记录或者引用方法的任务也只有委托类型的实例能够做到。
事件的本质
所以事件的本质时委托字段的一个包装器:
这个包装器对委托字段的访问起限制作用。
封装的一个重要功能就是隐藏。
事件对外隐藏了委托实例的大部分功能,仅暴露添加/移除事件处理器的功能。(就是只能+=,-=)
添加/移除事件处理器的时候可以直接使用方法名,这是委托实例不具备的功能。