用简单的代码测一测你是否真的了解:Asp.Net中的事件和委托的实现

简介: 页面:后台:代码        protected void Page_Load(object sender, EventArgs e)        {            Response.

页面:

<% @ Page Language = " C# "  CodeBehind = " Default.aspx.cs "  AutoEventWireup = " true "  Inherits = " WebApplication1._Default "   %>

后台:

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
         protected   void  Page_Load( object  sender, EventArgs e)
        {
            Response.Write(
" Page is loaded by Page_Load!<br> " );
        }

        
protected   override   void  OnLoad(EventArgs e)
        {
            Response.Write(
" Page is loaded by OnLoad!<br> " );
            
base .OnLoad(e);
        }

问题:

1.  如果 AutoEventWireup="false",输出会是什么?

2.  如果注释掉 base.OnLoad(e); 输出会是什么?

3.  关于其他 AutoEventWireup 设置和 base.OnLoad(e)注释与否的组合,结果各是什么?

 

之前我写过一篇文章换一个角度理解委托和事件 探讨了委托和事件的原理,这篇文章我想整理分析一下ASP.NET自己是如何利用委托和事件机制的。

 

这里首先给初学者介绍一个vs2008中的一个快捷键:F12;然后推荐一个工具:reflactor。很多时候,工具的使用比掌握某一个知识点更有用,所谓”授人以鱼,不如授人以渔“。F12可以转到方法的定义,reflactor则可以“反编译”.net程序集,是我们学习.net的利器啊,呵呵。


首先,如果 AutoEventWireup="false",我们会发现Page_Load方法根本不会执行(可设置断点查看)。如果你是直接学的asp.net2.0,很有可能你会忽视这个知识点(很不幸,我也是直接学的2.0)。AutoEventWireup是ASP.NET2.0一个新增的属性(具体可以查MSDN),它用于实现ASP.NET2.O页面事件的自动绑定!

我们回过头来想一想委托和事件吧! 我们常常说,页面事件,页面生命周期……,这些东西究竟是怎么被实现的呢?我们能够看到他们实现的代码么?

可以想象,Page_Load方法如果需要执行,必然应该和页面事件相关联。在Page这个类中,一定会暴露一个事件(如Onload);然后,我们还需要“订阅”事件,我更愿意通俗的说成将Page_Load方法和事件关联以来,让事件知道调用哪一个方法。但如何证实呢?线索呢?

 

用F12,首先。

public   partial   class  _Default : System.Web.UI.Page

将鼠标点到Page类上,按F12,vs2008自动跳转到System.Web.UI.Page代码页面,我们能找到以下代码:

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
         //  Summary:
        
//      Occurs when page initialization is complete.
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        
public   event  EventHandler InitComplete;
        
//
        
//  Summary:
        
//      Occurs at the end of the load stage of the page's life cycle.
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        
public   event  EventHandler LoadComplete;
        
//
        
//  Summary:
        
//      Occurs at the beginning of page initialization.
         public   event  EventHandler PreInit;
        
//
        
//  Summary:
        
//      Occurs before the page System.Web.UI.Control.Load event.
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        
public   event  EventHandler PreLoad;
        
//
        
//  Summary:
        
//      Occurs before the page content is rendered.
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        
public   event  EventHandler PreRenderComplete;
        
//
        
//  Summary:
        
//      Occurs after the page has completed saving all view state and control state
        
//      information for the page and controls on the page.
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        
public   event  EventHandler SaveStateComplete;

哇塞,都是事件哟!但很可惜,我们没能找到想要的OnLoad事件……

 

好在我们还有这行代码:

             base .OnLoad(e);

将鼠标点到OnLoad(e)上,再F12,哈哈,找到了:

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
         //
        
//  Summary:
        
//      Raises the System.Web.UI.Control.Load event.
        
//
        
//  Parameters:
        
//    e:
        
//      The System.EventArgs object that contains the event data.
         protected   internal   virtual   void  OnLoad(EventArgs e);

不容易啊,仔细一看,居然在Control类里,原来Page继承的是Control类,和我们一般的想法有点相反哟!(这里就不再展开了)更加注释,我们可以看出,这个方法就是raise(击发) Load事件的方法了!在这个Control类里,我们也能看到Load事件的声明:

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
         //
        
//  Summary:
        
//      Occurs when the server control is loaded into the System.Web.UI.Page object.
        [WebSysDescription( " Control_OnLoad " )]
        
public   event  EventHandler Load;

还可以看到事件绑定的委托EventHandler,再F12,我们能看到EventHandler的声明:

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
     //  Summary:
    
//      Represents the method that will handle an event that has no event data.
    
//
    
//  Parameters:
    
//    sender:
    
//      The source of the event.
    
//
    
//    e:
    
//      An System.EventArgs that contains no event data.
    [Serializable]
    [ComVisible(
true )]
    
public   delegate   void  EventHandler( object  sender, EventArgs e);

看到代码的感觉真爽,很踏实!是不是?

 

更精彩的还在reflactor,

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
protected   internal   virtual   void  OnLoad(EventArgs e)
{
    
if  ( this .HasEvents())
    {
        EventHandler handler 
=   this ._occasionalFields.Events[EventLoad]  as  EventHandler;
        
if  (handler  !=   null )
        {
            handler(
this , e);
        }
    }
}

和我们的想象有一点差别,但完全可以理解,而且你可以进一步的点击深入。

 

至此,我们可以梳理出ASP.NET的委托事件机制:
1.  .NET自有的委托EventHandler,确定了委托调用的方法签名(参数:sender和e,返回值void),这就是为什么我们看到的事件方法都长得一个样子的原因;

2.  在Page类及其父类中,的确是定义了一系列的事件和击发(raise)这些事件的方法。我们可以利用这些事件(如写Page_Load()方法),也可以直接override调用这些事件的方法(如OnLoad()方法)。这两者之间的区别或关系,以前我一直是晕的。

3.  因为AutoEventWireup的原因,我们没有看到“事件订阅”的代码,太遗憾了,所以我们接下来自己实现它:(首先AutoEventWireup=“false”)

         protected   override   void  OnInit(EventArgs e)
        {
            
            
base .OnInit(e);
            
this .Load  +=   new  EventHandler(Page_Load);
        }


 

现在,能回答本文开头的那些题目了吧?


 

 

 


 


 

相关文章
|
28天前
|
算法 Java 测试技术
使用 BenchmarkDotNet 对 .NET 代码进行性能基准测试
使用 BenchmarkDotNet 对 .NET 代码进行性能基准测试
57 13
|
5月前
|
API
【Azure 媒体服务】Media Service的编码示例 -- 创建缩略图子画面的.NET代码调试问题
【Azure 媒体服务】Media Service的编码示例 -- 创建缩略图子画面的.NET代码调试问题
|
1月前
|
开发框架 .NET PHP
ASP.NET Web Pages - 添加 Razor 代码
ASP.NET Web Pages 使用 Razor 标记添加服务器端代码,支持 C# 和 Visual Basic。Razor 语法简洁易学,类似于 ASP 和 PHP。例如,在网页中加入 `@DateTime.Now` 可以实时显示当前时间。
|
3月前
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
Android远程连接和登录FTPS服务代码(commons.net库)
49 1
|
3月前
|
前端开发 JavaScript C#
CodeMaid:一款基于.NET开发的Visual Studio代码简化和整理实用插件
CodeMaid:一款基于.NET开发的Visual Studio代码简化和整理实用插件
|
5月前
|
Kubernetes 监控 Devops
【独家揭秘】.NET项目中的DevOps实践:从代码提交到生产部署,你不知道的那些事!
【8月更文挑战第28天】.NET 项目中的 DevOps 实践贯穿代码提交到生产部署全流程,涵盖健壮的源代码管理、GitFlow 工作流、持续集成与部署、容器化及监控日志记录。通过 Git、CI/CD 工具、Kubernetes 及日志框架的最佳实践应用,显著提升软件开发效率与质量。本文通过具体示例,助力开发者构建高效可靠的 DevOps 流程,确保项目成功交付。
113 0
|
5月前
|
API
【Azure Key Vault】.NET 代码如何访问中国区的Key Vault中的机密信息(Get/Set Secret)
【Azure Key Vault】.NET 代码如何访问中国区的Key Vault中的机密信息(Get/Set Secret)
|
5月前
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
很多文章都介绍了FTPClient如何连接ftp服务器,但却很少有人说如何连接一台开了SSL认证的ftp服务器,现在代码来了。
127 2
|
5月前
|
微服务 API Java
微服务架构大揭秘!Play Framework如何助力构建松耦合系统?一场技术革命即将上演!
【8月更文挑战第31天】互联网技术飞速发展,微服务架构成为企业级应用主流。微服务将单一应用拆分成多个小服务,通过轻量级通信机制交互。高性能Java Web框架Play Framework具备轻量级、易扩展特性,适合构建微服务。本文探讨使用Play Framework构建松耦合微服务系统的方法。Play采用响应式编程模型,支持模块化开发,提供丰富生态系统,便于快速构建功能完善的微服务。
60 0
|
5月前
|
SQL 开发框架 .NET
代码更简洁,开发更高效:从零开始使用Entity Framework Core与传统ADO.NET构建数据持久化层的比较
【8月更文挑战第31天】在.NET平台上开发数据驱动应用时,选择合适的ORM框架至关重要。本文通过对比传统的ADO.NET和现代的Entity Framework Core (EF Core),展示了如何从零开始构建数据持久化层。ADO.NET虽强大灵活,但需要大量手写代码;EF Core则简化了数据访问,支持LINQ查询,自动生成SQL命令,提升开发效率。从创建.NET Core项目、定义数据模型、配置`DbContext`到执行数据库操作,EF Core提供了一套流畅的API,使数据持久化层的构建变得简单直接。
74 0

热门文章

最新文章