1

在现有的 ASP.NET 应用程序中,我有一个包含Page_Load方法的基类:

public class PageBaseClass : System.Web.UI.Page {
    protected virtual void Page_Load(object sender, EventArgs e) {
        // do stuff...
    }
}

我有一个从这个基类继承的实际页面。但是,它不会覆盖现有Page_Load方法,而是像这样声明一个新方法:

public class ActualPage : PageBaseClass {
    protected void Page_Load(object sender, EventArgs e) {
        // do other stuff...
    }
}

编译器警告我Page_Load实际页面中的方法正在隐藏现有Page_Load方法。如此有效,有两种单独Page_Load的方法,因为旧的方法没有被覆盖,而是隐藏了。

现在我的问题是,在这种情况下,ASP.NET 体系结构在其生命周期中做了什么?调用的是哪一个?或者他们都被称为?

注意:我知道这是一个糟糕的设计,我不确定原作者的想法,我只是想了解正在发生的事情以及这将如何影响系统的逻辑。

4

2 回答 2

1

经过一番挖掘,我发现了发生了什么。

简短的回答:只调用最顶层的方法!

起初,我设置了一些断点,例如 MelanciaUK 在评论中建议的。这向我表明只有最顶层的方法被调用。

深入挖掘,我查看了 volpav 的建议。设置为trueAutoEventWireup是真的,它会自动将方法连接到事件处理程序(因为这确实不是手动完成的)。然而,与他声称的不同,只有 topPage_Load方法被调用。

反思类型给了我一些线索:

var pageloads = this.GetType().GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).Where(m => m.Name == "Page_Load");
var pageload = this.GetType().GetMethod("Page_Load", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

pageloads值最终包含两个结果:两种Page_Load方法,一种具有声明类型ActualPage,另一种具有声明类型PageBaseClass

我虽然这会导致第二次调用出现问题,因为有两个结果,我希望它会抛出一个AmbiguousMatchException. 然而,它没有。它包含MethodInfofor 中的方法ActualPage

深入挖掘后,我偶然发现了 K. Scott Allen 的一篇文章:Inside AutoEventWireup http://odetocode.com/blogs/scott/archive/2006/02/16/inside-autoeventwireup.aspx

根据他的文章,连接事件发生如下:

Delegate.CreateDelegate(typeof(EventHandler), this, "Page_Load", true, false);

我自己执行这个,我发现这个调用创建了一个指向Page_Load方法的委托ActualPage,就像GetMethod调用返回那个方法一样。

因此,如果一个事件方法被自动连接起来,它似乎不会连接任何被隐藏的方法。

于 2013-04-05T14:21:04.557 回答
0

这两种方法中的代码都将被调用,因为它们本质上是一个事件处理程序(一个由基类附加,另一个由您的“ActualPage”类附加)。这是由于“AutoEventWireup”属性设置为“true”(默认情况下在您的标记中设置)。

关于“AutoEventWireup”的相关问题:AutoEventWireUp 页面属性是什么意思?

更新

原来我说这两种方法都将被调用是错误的,事实上,只有在“ActualPage”上声明的方法才会被调用。请参阅下面的 Rene 的答案。

于 2013-04-05T09:24:27.877 回答