我创建了一个asp.net页面,例如default.aspx.
然后定义一个按钮…
<asp:Button ID="btnNew" runat="server" Text="New" OnClick="btnNew_OnClick" />
…然而,我做没有在代码中定义btnNew_OnClick处理程序。
ASP。当我启动页面时,Net会告诉我这一点,并抛出一个异常。
因此,它是否使用反射来检查实现我的页面的类是否有这个方法?
这是有效的,如果它必须这样做,每次它解析一个页面的标记?
不特别。这发生在ASP。. NET编译ASPX标记。ASPX标记在第一次访问页面时编译,并存储在C:WINDOWSMicrosoft.NETFrameworkvXTemporary ASP.NET Files
中的某个位置。
如果使用aspnet_compiler.exe
预编译页面,则例外。然而,如果你要预编译它,你会在那里看到错误,而不是在你到达网站的时候。
这是有效的,如果它必须这样做,每次它解析一个页面的标记?
ASP。. NET不解析每个页面视图和发回的标记;它只在编译时解析它一次。它存储了页面的哈希值(通常称为hash.web
)在临时ASP的某个地方。. NET文件)并比较哈希值。如果哈希值不同(页面更改),则重新编译它。下面是编译后的代码的示例:
#line 58 "C:XUserControlsFilterControl.ascx"
@__ctrl.Click -= new System.EventHandler(this.btnApply_Click);
#line default
#line hidden
#line 58 "C:XUserControlsFilterControl.ascx"
@__ctrl.Click += new System.EventHandler(this.btnApply_Click);
这当然被编译成一个可执行程序集。实际上,ASPX编译器正在做的是将服务器端标记编译成c#代码,然后将其编译成程序集。
NET实际上使用ASPX标记作为各种模板从页面生成一个类。您可以在%WINDIR%Microsoft下的文件夹中找到生成的类源代码。. NETv[框架版本]网络文件。
我的理解是它生成一个实例化控件的类,并将事件处理程序连接到任何方法。这就是为什么当你把你的事件处理程序设为私有——后代类不能访问它的原因。
代码生成前期是相当昂贵的;它部分地导致了我们大多数asp.net开发人员所经历的漫长的asp.net预热。但是,一旦应用程序预热,它是非常非常高效的,因为所有内容都是通过编译代码渲染的。
不使用反射。正如@Wyatt Barnett所说,编译器为此生成代码。生成的代码与您自己注册事件的代码相同。
btnNew.Click += new EventHandler(btnNew_Click);
当生成标记代码时,它在性能方面是相同的,可能除了第一次调用。