C# 事件(订阅事件和触发事件)

发布于:2025-07-04 ⋅ 阅读:(16) ⋅ 点赞:(0)

订阅事件

订阅者向事件添加事件处理程序。对于一个要添加到事件的事件处理程序来说,它必须具有
与事件的委托相同的返回类型和签名。

  • 使用+=运算符来为事件添加事件处理程序,如下面的代码所示。事件处理程序位于该运
    算符的右边。
  • 事件处理程序的规范可以是以下任意一种:
    • 实例方法的名称;
    • 静态方法的名称;
    • 匿名方法;
    • Lambda表达式。

例如,下面的代码为CountedADozen事件添加了3个方法:第一个是实例方法,第二个是实
例静态方法,第三个是使用委托形式的实例方法。

image
和委托一样,我们可以使用匿名方法和Lambda表达式来添加事件处理程序。例如,如下代
码先使用Lambda表达式然后使用了匿名方法。

//Lambda表达式
incrementer.CountedADozen+=()=>DozensCount++;

//匿名方法
incrementer.CountedADozen+=delegate{DozensCount++;}

触发事件

事件成员本身只是保存了需要被调用的事件处理程序。如果事件没有被触发,什么都不会发
生。我们需要确保有代码在合适的时候做这件事情。
例如,如下代码触发了CountedADozen事件。注意如下有关代码的事项。

  • 在触发事件之前和null进行比较,从而查看事件是否包含事件处理程序。如果事件是null,
    则表示没有事件处理程序,不能执行。
  • 触发事件的语法和调用方法一样:
    • 使用事件名称,后面跟着参数列表(包含在圆括号中);
    • 参数列表必须与事件的委托类型相匹配。

image
把事件声明和触发事件的代码放在一起便有了如下的发布者类声明。这段代码包含了两个成
员:事件和一个叫作DoCount的方法,该方法将在适当的时候触发该事件。

class Incrementer
{
    public event EventHandler CountedADozen;    //声明事件

    void DoCount(object source,EventArgs args)
    {
        for(int i=1;i<100;i++)
        if(i%12==0)
            if(CountedADozen!=null)             //确认有方法可以执行

            CountedADozen(source,args);         //触发事件
    }
}

图15-5中的代码展示了整个程序,包含发布者类lncrementer和订阅者类Dozens。代码中需
要注意的地方如下:

  • 在构造函数中,Dozens类订阅事件,将IncrementDozensCount作为事件处理程序;
  • 在lncrementer类的DoCount方法中,每增加12个计数就触发CountedADozen事件。
class Incrementer //发布者
{
    public event Handler CountedADozen;     //创建事件并发布

    public void DoCount()
    {
        for(int i=1;i<100;i++)
            if(i%12==0&&CountedADozen!=null)
                CountedADozen();            //每增加12个计数触发事件一次
    }
}

class Dozens   //订阅者
{
    public int DozensCount{get;private set;}

    public Dozens(Incrementer incrementer)
    {
        DozensCount=0;

        incrementer.CountedADozen+=InCrementDozensCount;   //订阅事件
    }

    void InCrementDozensCount()
    {
        DozensCount++;               //声明事件处理程序
    }
}

class Program
{
    static void Main()
    {
        InCrementer incrementer=new Incrementer();
        Dozens dozensCounter=new Dozens(incrementer);

        incrementer.DoCount();
        Console.WriteLine("Number of dozens={0}",
                                dozensCounter.DozensCount);
    }
}