很多人都知道事件,一般定义一个事件是这样的写法

public event EventHandler OneEvent;

但是如果这样定义的话就需要进行null判断了

于是很多人这样定义事件:

public event EventHandler OneEventNeverNull = (o, e) => { };

这样就不需要判断null了。

上面的事件你可以把它认为是实例事件. 我们这里要谈的是静态事件(static event).

静态事件和实例事件的区别是加了个static 关键字,可别小看这个关键字,区别大了。

首先静态事件的定义为:

public static event EventHandler OneStaticEvent;

如果想要注册事件的话,那么必须使用类。

在.net 的事件里面,绝大多数是实例事件,但是却存在极少数的静态事件。

关于静态事件StackOverflow 上面有篇文章讨论它

地址如下:http://stackoverflow.com/questions/7045595/how-do-static-events-compare-to-non-static-events-in-c

我个人认为答案都不错,选了几个,试着翻译如下:

大部分的面向对象程序都可以被认为是消息的传递。

一个方法调用就是调用者发送给被调用者的携带参数的一个消息,和一个使用return value 做为返回值的消息。

一个事件是从source到订阅者的一个消息。因此就有两个实例参与其中,一个用来发送消息,另一个接收它。

但是静态事件,没有发送的实例(只是一个类型,它可能是也可能不是一个class)。

使用 静态事件的时候,要谨记,当一个对象订阅了一个静态事件,事件就持有了这个对象的引用,这就意味着你必须非常小心的显式的取消订阅事件,因为静态事件保留了对象引用,所以这些对象就永远不会被回收,你很可能碰到内存泄漏。

这些答案都说明了静态事件的一些特性。总结下:

1:静态事件没有发送的实例对象。

2:静态事件必须取消订阅,否则对象无法释放,事实上任何事件都应该取消订阅,有始有终。

对于第二点没有什么好考虑的,可是第一点?

静态事件没有发送的实例?

a:这代表静态事件不需要实例就可以,它代表的是类级别的事件。

b:这代表静态事件没有实例,或者说无法获取这个类的实例,所以使用静态事件。

从这两个理解,我们可以知道什么时候应该使用静态事件了。

a:从面向对象的角度,如果一个对象只想获取事件的通知,而不关心是谁发送的,它只关心事件发生。

b:这个类没有实例?,什么类没有实例???,静态类,抽象类,或者是一些特殊的类。

好了,我不卖关子了,让我们看看framework里面的静态事件吧,代码如下:

Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();foreach (Assembly assembly in assemblies)
{foreach (Type type in assembly.GetTypes()){EventInfo[] events = type.GetEvents(BindingFlags.Public | BindingFlags.Static);if (events.Length > 0){Console.WriteLine(type.ToString());}}
}
结果如下:
 

微软的开发人员只为这些类定义了静态事件,最后一个是我自己写的,我们看下这些究竟是些什么类。

System.Console

静态类,无法获取类的实例,所以静态事件。


System.Threading.Tasks.TaskScheduler

抽象类,它的静态事件定义如下:

//     当出错的 System.Threading.Tasks.Task 的未观察到的异常将要触发异常升级策略时发生,默认情况下,这将终止进程。public static event EventHandler<UnobservedTaskExceptionEventArgs> UnobservedTaskException;

只要应用程序注册了 UnobservedTaskException 事件,任何TaskScheduler的子类在发生exception的时候,都会通知到应用程序。

System.Diagnostics.Eventing.EventProviderDataStream

没找到。。。

System.Diagnostics.Contracts.Contract

静态类,无法获取类的实例,所以静态事件。

System.Windows.Forms.Application

密封类,构造函数为私有,外界无法直接获取Application 的实例。

System.Windows.Forms.ToolStripManager

密封类,构造函数为私有,外界无法直接获取实例。


System.ComponentModel.TypeDescriptor

密封类,构造函数为私有,外界无法直接获取实例。

Microsoft.Win32.SystemEvents

密封类,构造函数为私有,外界无法直接获取实例。

System.Net.NetworkInformation.NetworkChange

密封类,构造函数为私有,外界无法直接获取实例。

StaticEventDemo.Test

出现的理由:在某天夜晚,我自己想当然的写下的没有经过思考的一个静态事件。

你知道微软使用静态事件的策略了吗?,只有在不能获取实例的情况下才选择静态事件。

有趣的一件事:本人在baidu下搜索:static event, 看到了一篇文章:

net 在类中的Event事件,为什么可以定义为static?而委托类型却不可以

也可以在这里http://www.2cto.com/kf/201110/108280.html看到代码。

我看到了下面的这段:

private void button1_Click(object sender, EventArgs e)
{
            clsEvent clsevent = new clsEvent();
            //改变属性,从而激发事件。
            clsevent.StrContent = this.textBox1.Text;
}

我很想说,在改变属性前,是不是要注册点什么啊,我想这就是他为什么定义为static event的原因吧。

总结:

在无法获取实例的情况下,又想获得通知,应该使用静态事件。

不管发送者是谁,只考虑接收事件。

静态事件一定要取消订阅,否则内存泄漏。

想要获取静态类的通知时,使用静态事件。

想要得到静态属性和方法的通知的时候。

转载于:https://www.cnblogs.com/LoveJenny/archive/2013/01/30/2882383.html

关于静态事件 static event 的二三事相关推荐

  1. Revit空闲事件(Idling Event)增强和外部事件(External Event)

    关注公众号及时获取文章更新 1.外部实现步骤 (1)新建一个继承并实现外部事件(IEternalEventHandler)接口的类(该类的实例会被注册到Revit中),该接口包括两个需要实现的方法:E ...

  2. 2020年,关于事件相机(event camera)的最新研究论文总结

    本文仅用于学习过程中的一些总结记录.2020年发表的关于事件相机在一些领域的总结. 1. 运动估计 Motion Estimation 有不少关于运动估计的论文,基本是围绕之前最大化事件积累图对比度的 ...

  3. WinForm二三事(一)消息循环

    在进入正文之前,想请大家先欣赏下面两段代码: 1: //这是一个控制台程序,请先添加System.Windows.Form.dll的引用 2: using System.Windows.Form; 3 ...

  4. js进阶课程 12-9 jquery的事件对象event的方法有哪些?

    js进阶课程 12-9 jquery的事件对象event的方法有哪些? 一.总结 一句话总结:三组六个,阻止默认事件一组,阻止冒泡一组,阻止冒泡和剩余事件一组. 1.事件的默认动作指什么? 比如点a标 ...

  5. C#事件(Event)的理解

    文章目录 C#事件(Event)的理解 **事件的定义:** 事件的类型 C#事件(Event)的理解 事件的定义: C# 事件(Event): 基本上说是一个用户操作,如按键.点击.鼠标移动等等,或 ...

  6. 技术干货 | JavaScript 之事件循环(Event Loop)

    导读:学过 JavaScript(下文简称 JS) 的都知道它是一门单线程的.非阻塞的脚本语言.单线程意味着,JS 代码在执行的任何时候,都只有一个主线程来处理所有的任务,这也就意味着 JS 无法进行 ...

  7. C#——事件(Event)DEMO[闻鸡起舞]

    问题描述 (1) 创建 C#控制台应用程序. (2) 在程序中新建一个表示太阳的类Sun,在其中定义一个事件OnRise,一个成员方法Rise,并在方法中引发事件.参考源代码如下(太阳只有一个,所以将 ...

  8. 第53天:鼠标事件、event事件对象

    -->鼠标事件 -->event事件对象 -->默认事件 -->键盘事件(keyCode) -->拖拽效果 一.鼠标事件 onclick ---------------鼠 ...

  9. JavaScript:事件对象Event和冒泡

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 绑定事件的两种方式 我们在上一篇文章 DOM操作详解 中已经讲过事件的概 ...

  10. LiteOS内核源码分析:静态内存Static Memory

    本文分享自华为云社区<LiteOS内核源码分析系列十二 静态内存Static Memory>,原文作者:zhushy . 内存管理模块管理系统的内存资源,它是操作系统的核心模块之一,主要包 ...

最新文章

  1. ​GNN教程:Weisfeiler-Leman算法!
  2. linux vim编辑器主要作用,Linux-vim编辑器
  3. ArrayList深入解析,看这篇就够了
  4. 毫无疑问的是.NET 在信创常用软件适配清单之中
  5. A+B Problem(洛谷-P1001)
  6. PclZip:强大的PHP压缩与解压缩zip类
  7. vue3 element-ui el-date-picker选择日期后,悬停至日期icon时切换为清空icon
  8. 怎样组建云计算机,如何搭建云计算平台_搭建云计算平台步骤
  9. java-DBUtils的练习题
  10. 如何让js在浏览器宽度改变的时候执行一个函数?浏览器宽度变化
  11. CRC循环校验码的计算
  12. PythonーーJetBrains PyCharm安装
  13. 前端-深克隆与浅克隆
  14. 三月月赛 1005 wuli通通和doge(细节处理)
  15. CopyOnWriteArrayList 有什么特点?
  16. 怎么添加桌面计算机快捷键,怎么添加桌面快捷方式图标,教你怎么添加桌面快捷方式图标...
  17. 5类网线,超5类网线,6类网线,超6类网线的区别
  18. Hotspot 对象引用Reference和Finalizer 源码解析
  19. 基于python的数字图像处理--学习笔记(三)
  20. Python:orator/backpack内置数据操作类Collection

热门文章

  1. 调用目标检测百度接口api
  2. 卷积神经网络CNN经典模型整理(AlexNet,GoogleNet,VGG,Deep Residual Learning)
  3. caffe 实践程序4——cifar10网络
  4. 基于堆叠卷积长短期神经网络【CNNLSTM】模型的时序数据预测分析
  5. 基于Python从头开始使用 RMSProp 进行梯度下降
  6. Ubuntu16.04下安装、配置Sublime运行环境
  7. linux基础(二)——linux各文件夹含义和作用
  8. java redis3.0_Java + Redis(第三章)
  9. php 数组 判断可以吗,php判断一个数组是否为有序
  10. Graham 三参数表示法 详解