文章目录
事件
使对象或类具备通知能力的成员。
对象O拥有一个事件E:当事件E发生的时候,O有能力通知别的对象。
事件模型(发生->响应)
组成部分:
- 事件拥有者(event source对象)
- 事件成员(成员)
- 事件响应者(event subscriber 对象)
- 事件处理器(Event Handler,本质上是一个回调方法)
- 事件订阅
我有一个事件->一个人或者一群人关心我的这个事件->我的这个事件发生了->关心这个事件的人会被依次通知到->被通知到的人根据事件参数对事件进行相应(处理事件)
class Program
{
static void Main(string[] args)
{
Timer timer = new Timer();//事件拥有者
timer.Interval = 1000;
Boy boy = new Boy();//事件响应者
Girl girl = new Girl();
timer.Elapsed += boy.Action;// Elapsed 是事件 +=是订阅,boy.Action事件处理器
timer.Elapsed += girl.Action;
timer.Start();
Console.Read();
}
}
class Boy
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Jump");
}
}
class Girl
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Sing");
}
}
事件语法
事件拥有者和事件响应者 分别是两个对象
实现1
class Program
{
static void Main(string[] args)
{
Form form = new Form();//事件拥有者
Controller controller = new Controller(form);//事件响应者
form.ShowDialog();
}
}
class Controller
{
private Form form;
public Controller(Form form)
{
if (form!=null)
{
this.form = form;
this.form.Click += this.FormClicked;//事件 订阅 事件处理器
}
}
private void FormClicked(object sender, EventArgs e)
{
this.form.Text = DateTime.Now.ToString();
}
}
实现2
//sender包含的是事件拥有者,e表示事件参数
class Program
{
static void Main(string[] args)
{
Form form = new Form();//事件拥有者
Controller controller = new Controller();//事件响应者
form.Click += controller.FormClicked;
form.ShowDialog();
}
}
class Controller
{
public void FormClicked(object sender, EventArgs e)
{
//sender包含的是事件拥有者,e表示事件参数
Form form = (Form)sender;
form.Text = DateTime.Now.ToString();
}
}
事件的拥有者和事件的响应者是同一个对象
class Program
{
static void Main(string[] args)
{
MyForm form = new MyForm();
form.Click +=form.Action;
form.ShowDialog();
}
}
class MyForm : Form
{
internal void Action(object sender, EventArgs e)
{
Form form = (Form)sender;
form.Text = DateTime.Now.ToString();
}
}
事件的拥有者是事件响应者的一个成员
class Program
{
static void Main(string[] args)
{
MyForm myForm = new MyForm();//事件响应者
myForm.ShowDialog();
}
}
class MyForm : Form
{
private TextBox textBox;
private Button button;//事件拥有者
public MyForm()
{
this.textBox = new TextBox();
this.button = new Button();
this.button.Top = 30;
this.Controls.Add(this.textBox);
this.Controls.Add(this.button);
this.button.Click += this.ButtonClicked;//事件 订阅 响应
}
private void ButtonClicked(object sender, EventArgs e)
{
this.textBox.Text = "Hello World";
}
}
lambda表达式
this.button2.Click += (object sender, EventArgs e) =>
{ this.textBox1.Text = "lambda表达式"; };
声明自定义事件
完整的事件声明
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
Waiter waiter = new Waiter();
customer.Order += waiter.Action;
customer.InvokeEvent();
Console.Read();
}
}
class OrderEventArgs:EventArgs
{
public string Size { get; set; }
public string Name { get; set; }
}
//委托类型,为了声明事件。
delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
class Customer
{
public double Bill { get; set; }
public void PayTheBill()
{
Console.WriteLine("我付了{0}元",Bill);
}
//新添加一个事件,规定Order事件的事件处理器类型要遵守OrderEventHandler
private OrderEventHandler OrderEventHandler;
public event OrderEventHandler Order
{
add
{
this.OrderEventHandler += value;
}
remove
{
this.OrderEventHandler -= value;
}
}
//在内部触发事件
public void InvokeEvent()
{
Console.ReadLine();
if (this.OrderEventHandler!=null)
{
OrderEventArgs e = new OrderEventArgs() { Name = "火锅", Size = "small" };
this.OrderEventHandler.Invoke(this,e);
PayTheBill();
}
}
}
class Waiter
{
internal void Action(Customer customer, OrderEventArgs e)
{
if (e.Size=="small")
{
customer.Bill = 10;
}else
{
customer.Bill = 15;
}
Console.WriteLine("您点了{0},共{1}元",e.Name,customer.Bill);
}
}
简略的事件声明
//新添加一个事件,简化版(field-like)
public event OrderEventHandler Order;
//在内部触发事件
public void InvokeEvent()
{
Console.ReadLine();
if (this.Order != null)
{
OrderEventArgs e = new OrderEventArgs() { Name = "火锅", Size = "small" };
this.Order.Invoke(this, e);
PayTheBill();
}
}
事件的本质
事件的本事是委托字段的一个包装器,这个包装器限制了对委托字段的访问起了限制作用,事件对外界隐藏了委托实例的大部分功能,只暴露了添加/移除事件处理器的功能。
命名的约定
- 事件处理器一般命名为FooEventHandler;
- 一般事件拥有者用,object sender
- 事件参数用 eventArgs e
- 触发事件的方法一般命名为OnFoo,访问级别为protected
- 事件命名一般都是动词,还应注意时态,closing,closed
代码重构为:
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
Waiter waiter = new Waiter();
customer.Order += waiter.Action;
customer.Think();
customer.PayTheBill();
Console.Read();
}
}
class OrderEventArgs : EventArgs
{
public string Size { get; set; }
public string Name { get; set; }
}
//委托类型,为了声明事件。
class Customer
{
public double Bill { get; set; }
public void PayTheBill()
{
Console.WriteLine("我付了{0}元", Bill);
}
//新添加一个事件,简化版(field-like)
public event EventHandler Order;
//在内部触发事件
protected void OnOrder(string name,string size)
{
if (this.Order != null)
{
OrderEventArgs e = new OrderEventArgs() { Name = name, Size = size };
this.Order.Invoke(this, e);
}
}
public void Think()
{
Console.ReadLine();
this.OnOrder("huoguo", "small");
}
}
class Waiter
{
internal void Action(object sender, EventArgs e)
{
Customer customer = (Customer)sender;
OrderEventArgs e1 = (OrderEventArgs)e;
if (e1.Size == "small")
{
customer.Bill = 10;
}
else
{
customer.Bill = 15;
}
Console.WriteLine("您点了{0},共{1}元", e1.Name, customer.Bill);
}
}