事件聲明的完整格式
概念:
事件是基於委託的
- 事件需要使用委託類型來做約束,這種約束既規定了事件能夠發送什麼樣的消息給事件的響應者,也規定了事件的響應者能收到什麼樣的事件消息,這就決定了事件響應者的事件處理器必須能夠和這個約束匹配上,他才能訂閱這個事件。
- 當事件的響應者向事件的擁有者提供了能夠匹配這個事件的事件處理器之後呢,你總得找個地方把這個事件處理器保存記錄,能夠記錄或者引用方法的任務只有委託類型的實例才能做到。
很經典的餐館點菜的例子
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
Waiter waiter = new Waiter();
customer.Order += waiter.Action;
customer.Action();
customer.PayTheBill();
}
}
public class OrderEventArgs:EventArgs //聲明下菜單表,就是事件信息的格式
{
public string DishName { get; set; }
public string Size { get; set; }
}
//委託紙和筆記錄下哪桌的客戶點了什麼菜
public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
public class Customer //事件的擁有者
{
private OrderEventHandler orderEventHandler;
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 WalkIn()
{
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(2000);
}
if (this.orderEventHandler != null)//等於空,就是沒人訂閱你的事件,就是服務員比較忙,沒人響應你
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Kongpao Chicken";
e.Size = "large";
this.orderEventHandler.Invoke(this, e);
}
}
public void Action()
{
Console.ReadLine();
this.WalkIn();
this.SitDown();
this.Think();
}
}
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 = price * 0.5;
break;
case "large":
price = price * 1.5;
break;
default:
break;
}
customer.Bill += price;
}
}
}
簡略聲明
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
Waiter waiter = new Waiter();
customer.Order += waiter.Action;
customer.Action();
customer.PayTheBill();
}
}
public class OrderEventArgs:EventArgs //聲明下菜單表,就是事件信息的格式
{
public string DishName { get; set; }
public string Size { get; set; }
}
//委託紙和筆記錄下哪桌的客戶點了什麼菜
public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
public class Customer //事件的擁有者
{
public event OrderEventHandler Order;
public double Bill { get; set; }
public void PayTheBill()
{
Console.WriteLine("I will pay ${0}",this.Bill);
}
public void WalkIn()
{
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(2000);
}
if (this.Order != null)//等於空,就是沒人訂閱你的事件,就是服務員比較忙,沒人響應你
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Kongpao Chicken";
e.Size = "large";
this.Order.Invoke(this, e);
}
}
public void Action()
{
Console.ReadLine();
this.WalkIn();
this.SitDown();
this.Think();
}
}
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 = price * 0.5;
break;
case "large":
price = price * 1.5;
break;
default:
break;
}
customer.Bill += price;
}
}
}
有了委託字段/屬性,爲什麼還需要事件?
爲了程序的邏輯更加有道理和安全
事件的本質就是委託字段的一個包裝器
EventHandler委託
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer(); //事件的擁有者
Waiter waiter = new Waiter(); //事件的響應者
customer.Order += waiter.Action; //Customer發了一個Order事件
customer.Action();
customer.PayTheBill();
}
}
public class OrderEventArgs:EventArgs
{
public string DishName { get; set; }
public string Size { get; set; }
}
// public delegate void OrderEventHandler(Customer customer,OrderEventArgs e);
public class Customer
{
public event EventHandler Order;
public double Bill { get; set; }
public void PayTheBill()
{
Console.WriteLine("I will pay ${0}",this.Bill);
}
public void WalkIn()
{
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 (this.Order != null)
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Kongpao Chicken";
e.Size = "large";
this.Order.Invoke(this, e);
}
}
public void Action()
{
Console.ReadLine();
this.WalkIn();
this.SitDown();
this.Think();
}
}
public class Waiter
{
public void Action(object sender, EventArgs e)
{
Customer customer = sender as Customer;
OrderEventArgs orderInfo = e as OrderEventArgs;
Console.WriteLine("I will serve you the dish {0}",orderInfo.DishName);
double price = 10;
switch (orderInfo.Size)
{
case "small":
price = price * 0.5;
break;
case "large":
price = price * 1.5;
break;
default:
break;
}
customer.Bill += price;
}
}
}