C#中的事件

事件模型的五个组成部分

  1. 事件的拥有者(event source,对象)
  2. 事件成员(event,成员)
  3. 事件的响应者(event subscriber,对象)
  4. 事件处理器(event hander,成员)——本质上是一个回调方法
  5. 事件订阅——把事件处理器与事件关联在一起,本质上是一种以委托类型为基础的“约定”

模式一

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace EventExample
{
    class Program
    {
        static void Main(string[] args)
        {
            //1. 事件的拥有者
            Timer timer = new Timer();
            //设置时间间隔
            timer.Interval = 1000;//1000ms
            //2.事件的响应者
            Boy boy = new Boy();
            Girl girl = new Girl();
            //3.事件Elapsed 5.订阅 +=
            timer.Elapsed += boy.Action1;
            timer.Elapsed += girl.Action2;
            timer.Start();
            Console.ReadLine();

            ;
        }
    }
    class Boy
    {
        //4.事件的处理器
        internal void Action1(object sender, ElapsedEventArgs e)
        {
            Console.WriteLine("Jump");
        }
    }
    class Girl
    {
        internal void Action2(object sender, ElapsedEventArgs e)
        {
            Console.WriteLine("Singing");
        }
    }
}

模式二

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Event2
{
    class Program
    {
        static void Main(string[] args)
        {
            //1. 事件拥有者this.form
            Form form = new Form();
            //4. 事件的响应者:controller
            Controller controller = new Controller(form);
            form.ShowDialog();
        }
    }
    class Controller
    {
        private Form form;
        //构造器
        public Controller(Form form)
        { 
            this.form = form;
            //2 事件:this.form.Click
            //5. 订阅关系
            this.form.Click += this.FormClicked;
        }

        //3.事件的处理器
        private void FormClicked(object sender, EventArgs e)
        {
            this.form.Text = DateTime.Now.ToString();
        }
    }
}

模式三

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Event3
{
    class Program
    {
        static void Main(string[] args)
        {
            MyForm myForm = new MyForm();
            myForm.Click += myForm.Clicked;
            myForm.ShowDialog();
        }
    }
    class MyForm : Form
    {
        internal void Clicked(object sender, EventArgs e)
        {
            this.Text = DateTime.Now.ToString();
        }
    }
}

模式四

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Event4
{
    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.Controls.Add(this.textBox);
            this.Controls.Add(this.button);
            this.button.Click += this.ButtonClicked;
            this.button.Text = "Say Hello";
            this.button.Top = 100;
        }

        private void ButtonClicked(object sender, EventArgs e)
        {
            this.textBox.Text = DateTime.Now.ToString();
        }
    }
}

事件与委托的关系

事件真的是“以特殊方式声明的委托字段/实例”吗?

  • 不是!只是声明的时候“看起来像”(对比委托字段与时间的简化声明,field-like)
  • 事件声明的时候使用了委托类型,简化声明造成事件看上去像一个委托的字段(实例),而event关键字则更像是一个修饰符——错觉来源之一
  • 订阅事件的时候+=操作符后面可以是一个委托实例,这与委托实例的赋值方法语法相同,这也让事件看起来像是一个委托字段——错觉来源之二
  • 重申:事件的本质是加装在委托字段上的一个蒙版(mask),是一个起掩蔽作用的包装器。这个用于阻挡非法操作的蒙版绝不是委托字段本身。

为什么要使用委托类型来声明事件?

  • 站在source的角度来看,是为了表明source能对外传递哪些消息
  • 站在subscriber的角度来看,它是一种约定,是为了约束能够使用什么样签名的方法来处理(响应)事件
  • 委托类型的实例将用于存储(引用)事件处理器

对比事件和属性

  • 属性不是字段——很多时候属性是字段的包装器,这个包装器用来保护字段不被滥用
  • 事件不是委托字段——它是委托字段的包装器,这个包装器用来保护委托字段不被滥用
  • 包装器永远都不可能是被包装的东西。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值