C# 事件

2018-01-16 02:34 更新

C#事件

事件系统是软件系统的核心部分。例如,按钮可以触发点击事件。批处理作业可以生成作业完成事件。学生系统将使用注册事件。

广播者是包含委托字段的类型。

广播者决定何时广播,通过调用委托。

订阅者是方法目标收件人。

订阅者通过在广播者的委托上调用+ =和 - =决定何时开始和停止侦听。

事件是一个C#语言功能,正式化这种模式。

例子

要声明事件,请将事件关键字放在代理成员的前面:

// a delegate
public delegate void ValueChangedHandler (decimal oldPrice, decimal newPrice);

public class Broadcaster {
   // Event declaration
   public event ValueChangedHandler PriceChanged;
}

Broadcaster 类型中的代码具有对 PriceChanged 的完全访问权限,可以将其视为代理。

Broadcaster 外部的代码只能对PriceChanged 事件执行+ =和 - =操作。


标准事件模式

.NET Framework定义了用于写入事件的标准模式。

System.EventArgs是一个没有成员的预定义的Framework类。

EventArgs 是一个承载事件信息的基类。

以下代码将 EventArgs 子类化,以启动PriceChanged 事件时存储旧价格和新价格:

public class PriceChangedEventArgs : System.EventArgs {
    public readonly decimal LastPrice;
    public readonly decimal NewPrice;
    public PriceChangedEventArgs (decimal lastPrice, decimal newPrice) {
        LastPrice = lastPrice;
        NewPrice = newPrice;
    }
}

EventArgs 子类根据其包含的信息命名。

它通常将数据作为属性或作为只读字段公开。

创建 EventArgs 子类之后,下一步是为事件定义一个委托,它是事件处理程序委托。

事件处理程序委托必须有一个void返回类型。

事件处理程序委托必须接受两个参数:第一个是类型对象,第二个是EventArgs的子类。

第一个参数指示事件广播者,第二个参数包含要传达的额外信息。

事件处理程序委托的名称必须以 EventHandler 结尾。

框架定义了一个称为 System.EventHandler<> 的通用委托,它满足这些规则:


public 
delegate 
void 
EventHandler<TEventArgs> (object source, TEventArgs e) 
where TEventArgs : EventArgs;

以下代码定义了我们的值更改事件的委托。

public delegate void ValueChangedHandler (object sender, PriceChangedEventArgs e);

下一步是定义所选委托类型的事件。

在这里,我们使用通用 EventHandler 委托:

public class Product {
    public event EventHandler<PriceChangedEventArgs> PriceChanged;
}

最后,该模式需要您编写一个受保护的虚拟方法来触发事件。

该名称必须与事件的名称匹配,前缀为单词On,并接受单个EventArgs参数:

public class Product {
    ...
    public event EventHandler<PriceChangedEventArgs> PriceChanged;
    protected virtual void OnPriceChanged (PriceChangedEventArgs e) {
        if (PriceChanged != null) PriceChanged (this, e);
    }
}

例2

这里是完整的例子:


using System;

public class PriceChangedEventArgs : EventArgs {
    public readonly decimal LastPrice;
    public readonly decimal NewPrice;

    public PriceChangedEventArgs (decimal lastPrice, decimal newPrice) {
        LastPrice = lastPrice; NewPrice = newPrice;
    }
}

public class Product {
    string symbol;
    decimal price;

    public Product (string symbol) {
       this.symbol = symbol;
    }
    
    public event EventHandler<PriceChangedEventArgs> PriceChanged;
    
    protected virtual void OnPriceChanged (PriceChangedEventArgs e) {
        if (PriceChanged != null) {
           PriceChanged (this, e);
        }
    }
    public decimal Price {
       get { 
          return price; 
       }
       set {
         if (price == value) return;
         decimal oldPrice = price;
         price = value;
         OnPriceChanged (new PriceChangedEventArgs (oldPrice, price));
      }
    }
}
class Test {
     static void Main()  {
        Product stock = new Product ("THPW");
        stock.Price = 2.10M;
        // Register with the PriceChanged event
        stock.PriceChanged += stock_PriceChanged;
        stock.Price = 3.9M;
     }
     static void stock_PriceChanged (object sender, PriceChangedEventArgs e) {
         if (e.NewPrice - e.LastPrice > 0){
             Console.WriteLine ("Alert!");
         }
     }
}

事件访问器和修饰符

事件的访问器是其 + = - = 函数。

默认情况下,访问器由编译器隐式实现。

像方法一样,事件可以是虚拟的,重写的,抽象的或密封的。

事件也可以是静态的:


public class Product {
    public static event EventHandler<EventArgs> StaticEvent;
    public virtual event EventHandler<EventArgs> VirtualEvent;
}
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号