惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
D
Docker
云风的 BLOG
云风的 BLOG
F
Fortinet All Blogs
F
Full Disclosure
H
Hackread – Cybersecurity News, Data Breaches, AI and More
P
Proofpoint News Feed
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
L
LangChain Blog
H
Help Net Security
B
Blog
T
Tailwind CSS Blog
V
V2EX
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
Recent Announcements
Recent Announcements
aimingoo的专栏
aimingoo的专栏
美团技术团队
A
About on SuperTechFans
C
Cybersecurity and Infrastructure Security Agency CISA
K
Kaspersky official blog
I
InfoQ
Project Zero
Project Zero
I
Intezer
Google DeepMind News
Google DeepMind News
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Threat Research - Cisco Blogs
Last Week in AI
Last Week in AI
C
Cyber Attacks, Cyber Crime and Cyber Security
G
GRAHAM CLULEY
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
AWS News Blog
AWS News Blog
Spread Privacy
Spread Privacy
S
Securelist
Recorded Future
Recorded Future
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 叶小钗
S
Security Affairs
Blog — PlanetScale
Blog — PlanetScale
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
The Hacker News
The Hacker News

博客园 - 昊子

工作流参考模型(Workflow Reference Model) DNN default document的异常错误 如何使用GoogleCode提供的SVN Source Control服务 Norton PartitionMagic 8.0 Resizing Boot Partition 智能提示和那些值得崇拜的人 推荐一个Flex & AIR皮肤站点 SessionDiskCache 0.1版发布 Flex locale Flex Repeater 多层嵌套 从没走远 SubmitMask 1.0 发布 如何获取Footer中的子控件 DNN学习笔记 之一 配置 使用NHibernate时产生的一个错误 NHibernate官方文档 之 NHibernate指南-前言 C#反转单向链表 静态构造函数和静态成员变量初始化的调用时间 NHibernate和SqlImage 结束无谓的讨论吧
C#事件编程
昊子 · 2006-06-21 · via 博客园 - 昊子

开发时,我们几乎无时无刻不用到事件。然而对于初级开发者,包括我自己,大多数用的都是.net类库中的事件。
先看看例子:

            this.Load += new System.EventHandler(this.Page_Load);

这个估计是asp.net最常用的事件了。将Page对象的Load事件委托到Page_Load()方法进行处理。

看看各成员的类型:
this 是System.Web.UI.Page类型
this.Load 是System.EventHandler类型的事件event
对象浏览器对Page.Load的解释

public event System.EventHandler Load
    System.Web.UI.Control 的成员

摘要:
 当服务器控件加载到 System.Web.UI.Page 对象中时发生。  


SystemEventHandler 是一个delegate委托,原形是

[C#]
[Serializable]
public delegate void EventHandler(
   
object sender,
   EventArgs e
);

在mscorlib包,也就是.net基础框架中。VS.net2003对象浏览器如是解释

public sealed delegate EventHandler : System.MulticastDelegate
    System 的成员

摘要:
 表示将处理不包含事件数据的事件的方法。  


this.Page_Load是一个void方法

使用过程是这样,所有事件相关的东西都要依赖于一个委托delegate,先声明委托。delegate void SomeDelegate();
然后在类中定义一个该委托类型的事件:event SomeDelegate AnEvent;
在然后在对象实例化之后,事件发生之前(当然大部分是在构造函数中)将一个方法连接到委托
this.AnEvent += new SomeDelegate(this.EventRaise);
同时声明一个方法
void EventRaise(){}
最后在需要引发事件的地方调用this.AnEvent()

看个例子

    class Class1
    
{
        [STAThread]
        
static void Main(string[] args)
        
{
            Test test 
= new Test();
        }

    }

    
public delegate void GeneralEvent_Raise () ;

    
public class Test
    
{
        
public event GeneralEvent_Raise GeneralEvent ;
        
public Test()
        
{
            GeneralEvent 
+= new GeneralEvent_Raise(Test_GeneralEventRaise);
            GeneralEvent();
        }


        
public void Test_GeneralEventRaise()
        
{
            System.Console.WriteLine(
"Raise!");
        }

    }


代码比较简单,不详细说了。这样在运行时就会看到输出“Raise!”。
看到+=突然产生兴趣,既然不是直接用“=”,是不是可以把一个事件连接到多个委托
修改Test构造函数

        public Test()
        
{
            GeneralEvent 
+= new GeneralEvent_Raise(Test_GeneralEventRaise);
            GeneralEvent 
+= new GeneralEvent_Raise(Test_GeneralEventRaise);
            GeneralEvent();
        }

再运行看到什么?是的,一个事件引发了两个处理。那么如何去掉委托呢

        public Test()
        
{
            GeneralEvent 
+= new GeneralEvent_Raise(Test_GeneralEventRaise);
            GeneralEvent 
= null;
            GeneralEvent += new GeneralEvent_Raise(Test_GeneralEventRaise);

            GeneralEvent();
        }

再看看,只触发了一次。用什么办法制定只有一个委托处理事件呢

            GeneralEvent += new GeneralEvent_Raise(Test_GeneralEventRaise);
            GeneralEvent 
= new GeneralEvent_Raise(Test_GeneralEventRaise);

仍然是一次。
不知道不给事件定委托是什么样子

        public Test()
        
{
            GeneralEvent();
        }

异常了吧。如果想自定异常可以这样做

            if ( GeneralEvent != null )
            
{
                GeneralEvent();
            }

            
else
            
{
                
throw new Exception("事件不会被处理!");
            }

在被依赖项目中定义好委托和事件,在下级项目中实现委托并把委托+到事件上,对于一些设计时未知的处理效果会相当好