.NET框架为事件定义了一个标准模式,它的目的是保持框架和用户代码之间的一致性。

标准事件的模式核心是SystemEventArgs——预定义的没有成员的框架类(不同于静态Empty属性)

EventArgs表示包含事件数据的类的基类,并提供用于不包含事件数据的事件的值。用于为事件传递信息的基类。

在下面例子中,我们定义EventArgs的子类,用于事件PriceChanged被引发时,传递新旧Price值:

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

考虑到复用性,EventArgs子类根据它包含的内容命名(而非根据将被使用的事件命名)。

选择或定义事件的委托,需遵循三条原则:

  • 委托必须以void作为返回值
  • 委托必须接受两个参数:第一个是object类,第二个是EventArgs的子类。
  • 委托的名称必须以EventHandler结尾

完整例子:

class Test
public static void Main()
{
InitializeComponent();
Stock stock = new Stock("THPW");
stock.Price = 27.10M;
//注册PriceChanged事件
stock.PriceChanged += stock_PriceChanged;
stock.Price = 31.59M;
} static void stock_PriceChanged(object sender, PriceChangedEventArgs e)
{
if ((e.NewPrice - e.LastPrice) / e.LastPrice > 0.1M)
{
Console.WriteLine("Alert,10% stock increase!");
}
}
} public class Stock
{
string symbol;
decimal price; public Stock(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;
            price = value;
          OnPriceChanged(new PriceChangedEventArgs(price, value));

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

如果事件不传递额外的信息,可以使用预定义的非泛化委托EventHandler。如下所示:

    class Test
{
public static void Main()
{
InitializeComponent();
Stock stock = new Stock();
stock.Price = 27.10M;
//注册PriceChanged事件
stock.PriceChanged += stock_PriceChanged;
stock.Price = 31.59M;
} static void stock_PriceChanged(object sender, EventArgs e)
{
Console.WriteLine("价格变换了!");
}
} public class Stock
{
decimal price; public event EventHandler PriceChanged; protected virtual void OnPriceChanged(EventArgs e)
{
if (PriceChanged != null) PriceChanged(this, e);
} public decimal Price
{
get { return price; }
set
{
if (price == value) return;
price = value; //OnPriceChanged(new EventArgs()); OnPriceChanged(EventArgs.Empty);
}
}
}

注意:

上面例子中事件除了传递已发生信息,没有传递其他信息。

你可以使用 OnPriceChanged(new EventArgs()) 来完成事件的传递。

为了避免对EventArgs不必要的初始化,建议使用EventArgs.Empty属性。使用这样一个“空的”静态引用的对象,避免多余地去创建一个新对象。

微软的大部分控件所抛出的事件都有两个参数,第一个是 object 类型的,第二个是 EventArgs 类型的。

你从EventArgs  e那里得不到任何此次事件相关需要传递的信息,真正传递的信息都在sender中。

C# 标准事件模式的更多相关文章

  1. W3C对DOM2.0定义的标准事件

    DOM2.0模型将事件处理流程分为三个阶段: 一.事件捕获阶段, 二.事件目标阶段, 三.事件起泡阶段. 具体如图(图片来源于网络,侵删) 事件捕获:当某个元素触发某个事件(如onclick),顶层对 ...

  2. C#代码:用事件模式实现通知

    事件提供了一种标准的机制来通知监听者..NET的事件模式使用了事件语法来实现观察者模式.任意数量的客户对象都可以将自己的处理函数注册到事件上,然后处理这些事件.这些客户对象不需要再编译期就给出.时间也 ...

  3. 【转载】详细解读C#中的 .NET 弱事件模式

    你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处理中展 ...

  4. C#中的 .NET 弱事件模式

    引言 你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处 ...

  5. 标准IDispose模式浅析

    DoNet资源 众所周知,.Net内存管理分托管资源和非托管资源,把内存中的对象按照这两种资源划分,然后由GC负责回收托管资源(Managed Resource),而对于非托管资源来讲,就需要程序员手 ...

  6. CUDA 标准编程模式

    前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式编写,即使是调用库,库的底层也是这个模式实现的. 模式描述 1. 定义需要在 device 端执行的核函数.( 函数声明前加 ...

  7. 如何给ActiveX控件添加“事件”“属性”“标准事件”“自定义事件”等一些相关操作

    上一篇小编带大家熟悉了一下ActiveX的建立以及相关的概念,(http://blog.csdn.net/u014028070/article/details/38424611) 本文介绍下如何给控件 ...

  8. C#的内存管理原理解析+标准Dispose模式的实现

    本文内容是本人参考多本经典C#书籍和一些前辈的博文做的总结 尽管.NET运行库负责处理大部分内存管理工作,但C#程序员仍然必须理解内存管理的工作原理,了解如何高效地处理非托管的资源,才能在非常注重性能 ...

  9. [转]改善C#程序的建议4:C#中标准Dispose模式的实现

    需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...

随机推荐

  1. 清明梦超能力者黄YY(idx数组)

    清明梦超能力者黄YY https://www.nowcoder.com/acm/contest/206/I 题目描述 黄YY是一个清明梦超能力者,同时也是一个记忆大师.他能够轻松控制自己在梦中的一切, ...

  2. 根据二进制和十进制转换规则转换成游戏[xyytit]

    摘要: 二進位是由十進位轉換而成,它的數字都由1.0組成的.我們研究發現由十進位轉換而成的二進位的數字可以不只局限在於1~127,它的數可以更加深加廣,並且可以利用二進位的規則轉換成遊戲.我們利用2n ...

  3. time,datetime,时间戳 时间格式转换

    总结: time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) datetime.datetime.now().strftime( ...

  4. maven仓库的作用以及仓库的分类

    maven的工作需要从仓库下载一些jar包,如下图所示,本地的项目A.项目B等都会通过maven软件从远程仓库(可以理解为互联网上的仓库)下载jar包并存在本地仓库,本地仓库 就是本地文件夹,当第二次 ...

  5. web前端js 实现打印操作

    转载来源:https://www.cnblogs.com/potatog/p/7412905.html 一.打印当前页面指定元素中的内容 方式一:直接使用window.print(); (1)首先获得 ...

  6. db2 sql调优

    当我们发现某个SQL语句执行很慢时,可以通过查看它的访问计划来定位原因,如是否执行了合适的索引.是否采用了正确的连接方法等.但是我们发现很多用户对访问计划的生成和解释工具的使用存在很多疑惑,本文通过一 ...

  7. 调试Javascript代码(浏览器F12)

    在浏览器中按F12,会弹出一个窗口,这个窗口是给开发人员用于网站调试用的,可以分析网页的问题出现在哪里,同时可以调试多种脚本,是一个开发者工具. 想通过encodeURIComponent将C24\C ...

  8. Java数据结构和算法(三)顺序存储的树结构

    Java数据结构和算法(三)顺序存储的树结构 二叉树也可以用数组存储,可以和完全二叉树的节点一一对应. 一.树的遍历 // 二叉树保存在数组中 int[] data; public void preO ...

  9. apicloud管理

    以下所有操作都是指“apicloud”平台下的管理: 1. 一定要记得备份证书.证书不是因为你记得别名和密码就能还原的.因为apicloud是服务器session存数据,千万不要打开多个app操作页面 ...

  10. css心得体会

    非块级元素  要使得其有长宽的效果  可以设置  margin  和  padding 块级元素     可以直接设置  width  和  height div标签   要使得你内部元素居中   可 ...