C# 事件(Event)

C# 事件(Event)是一种成员,用于将特定的事件通知发送给订阅者。事件通常用于实现观察者模式,它允许一个对象将状态的变化通知其他对象,而不需要知道这些对象的细节。

  1. 事件的定义:使用 event 关键字定义事件,通常放在类的公共或私有部分。

  2. 委托:事件需要一个委托类型,委托是一种特殊的类型,定义了方法的签名。

  3. 事件的触发:使用 raise 关键字或 EventHandler 类的 Invoke 方法来触发事件。

  4. 事件的订阅和取消订阅:使用 +=-= 运算符来订阅和取消订阅事件。

事件是一种特殊的多播委托

它允许对象通知其他对象发生了某个事情。在 C# 中,事件通常用于以下几个目的:

  1. 通知:一个对象(发布者)通过事件向其他对象(订阅者)发送通知,告知它们某些事情已经发生。
  2. 解耦:事件提供了一种机制,使得订阅者不需要知道事件的发送者是谁,也不需要知道事件是如何被触发的,从而实现发布者和订阅者之间的松耦合。

事件主要包括三个部分:

1. 事件的订阅者(控件,比如:Button)
2. 事件的触发者(各种操作,比如:点击)
3. 订阅者和触发者之间的数据传输通道(事件句柄:一头连接着订阅者,一头连接着触发者)

事件基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件。

事件具体是什么:

(1)事件是委托实例,增加一个关键字Event,是特殊的委托(用委托生成的一个变量而异)
(2)事件只能在当前类被访问,子类和类外部均不能执行类中的事件方法(安全)
(3)委托和事件从本质上来说没啥区别(事件基于委托,没有委托,就没事件。)

事件本质:指委托的实例。事件肯定是委托,但委托不一定是事件。

C#语言中的事件:事件是委托的实例(个体),委托的实例不一定是事件,但事件肯定是委托的实例。事件是一种特殊的委托实例。

事件只能定义在类内部,不能在方法内部

internal class Program
{
    //定义一个事件,使用event关键字。,EventHandler委托类型  MyClick就是委托实例,即事件变量。
    public static event EventHandler MyClick;
    static void Main(string[] args)
    {
        //委托不一定是事件,但事件一定是委托
        //委托实例,不是事件
        EventHandler click1 = new EventHandler((sender, arg) => { });
        //定义事件,实例化事件(和委托实例化基本一致。只是第一初始化时,也可以使用+=或-=)
        MyClick = Program_MyClick;//第一次赋值
        MyClick += Program_MyClick1;//第二次赋值
        MyClick += delegate (object sender, EventArgs arg)
        {
            Console.WriteLine("匿名委托");
        };
        MyClick += (sender, arg) =>
        {
            Console.WriteLine("拉姆达语句");
        };
        //调用事件
        MyClick(null,null);
        MyClick.Invoke(null,null);
        Console.ReadKey();
    }
    private static void Program_MyClick(object sender, EventArgs e)
    {
        Console.WriteLine("第一次赋值");
    }
    private static void Program_MyClick1(object sender, EventArgs e)
    {
        Console.WriteLine("第二次赋值");
    }
}

EventHandler 和 EventHandler<TEventArgs>

  • EventHandler 是一个预定义的委托,用于没有事件数据的事件处理程序。它的签名是 void OnEvent(object sender, EventArgs e),其中 sender 是发送事件的对象,e 是包含事件数据的 EventArgs 类的实例。
  • EventHandler<TEventArgs> 是一个泛型委托,用于带有自定义事件数据的事件处理程序。这里的 TEventArgs 是从 EventArgs 类派生的自定义类,用于传递事件相关的数据。

声明和使用事件

以下是如何声明和使用 ButtonClickEvent 事件的示例:

  1. 声明事件

    例句
    public event EventHandler ButtonClickEvent;
  2. 触发事件: 在适当的时机(例如,当按钮被点击时),你可以触发这个事件。这通常通过创建一个 EventArgs 实例并调用每个订阅者的委托来完成。

    例句
    protected virtual void OnButtonClick()
    {
        ButtonClickEvent?.Invoke(this, EventArgs.Empty);
    }
  3. 订阅事件: 其他对象可以通过订阅这个事件来响应按钮点击。这通常在对象创建或初始化时完成。

    例句
    myButton.ButtonClickEvent += MyButtonClickHandler;
    
    private void MyButtonClickHandler(object sender, EventArgs e)
    {
        Console.WriteLine("Button was clicked!");
    }

在这个例子中,MyButtonClickHandler 方法是一个事件处理程序,它将在 ButtonClickEvent 事件被触发时执行。myButton.ButtonClickEvent += MyButtonClickHandler; 这行代码将这个方法订阅到事件上。

事件的最佳实践

  • 保护:通常,事件的访问器应该是 protected virtual,这样派生类可以提供自己的事件触发逻辑。
  • 使用疑问符:在触发事件时,使用 ?. 运算符可以避免在没有订阅者时引发 NullReferenceException
  • 线程安全:如果你的应用程序是多线程的,确保事件的触发和订阅是线程安全的。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值