Reputation: 3548
In an existing ASP.NET application, I have a base class containing a Page_Load
method:
public class PageBaseClass : System.Web.UI.Page {
protected virtual void Page_Load(object sender, EventArgs e) {
// do stuff...
}
}
I have an actual page which inherits from this base class. However, it doesn't override the existing Page_Load
method, but declares a new one like this:
public class ActualPage : PageBaseClass {
protected void Page_Load(object sender, EventArgs e) {
// do other stuff...
}
}
The compiler gives me a warning that the Page_Load
method in the actual page is hiding the existing Page_Load
method. So effectively, there are two seperate Page_Load
methods, since the old one wasn't overridden, but hidden.
Now my question is, what does the ASP.NET architecture do in it's lifecycle in such a situation? Which one is being called? Or are they both being called?
Note: I know this is bad design, I'm not sure what the original author had in mind, I'm just trying to understand what's happening and how this will affect the logic of the system.
Upvotes: 1
Views: 544
Reputation: 5128
The code in both methods will be called since these are essentially an event handlers (one which is attached by the base class, another one - by your "ActualPage" class). This is due to "AutoEventWireup" property set to "true" (it's set by default in your markup).
Related question on "AutoEventWireup": What does AutoEventWireUp page property mean?
UPDATE
Turned out I was wrong stating that both methods will be called and in fact, only the one declared on the "ActualPage" gets called. See Rene's answer below.
Upvotes: 0
Reputation: 3548
After some digging around, I've found out what's happening.
Short answer: only the top-most method is called!
At first I put down some breakpoints like MelanciaUK suggested in a comment. This showed me that only the top-most method was being called.
Digging deeper, I looked at what volpav suggested. It was true that AutoEventWireup
was set to true, which was automatically hooking up the method to the event handler (since this indeed wasn't done manually). However, unlike he claimed, only the top Page_Load
method was being called.
Reflecting over the type gave me a bit of a clue what was going on:
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);
The pageloads
value ended up containing two results: the two Page_Load
methods, one with declaring type ActualPage
and one with declaring type PageBaseClass
.
I though that would cause problems for the second call, since having two results, I expected it to throw an AmbiguousMatchException
. However, it did not. It contained the MethodInfo
for the method in the ActualPage
.
Digging deeper, I stumbled upon an article by K. Scott Allen: Inside AutoEventWireup http://odetocode.com/blogs/scott/archive/2006/02/16/inside-autoeventwireup.aspx
According to his article, wiring up events is happening as follows:
Delegate.CreateDelegate(typeof(EventHandler), this, "Page_Load", true, false);
Executing this myself, I found that this call creates a delegate pointing at the Page_Load
method for the ActualPage
, the same way the GetMethod
call returned that method.
So it seems that in case an event-method is being wired up automatically, it will not wire up any methods that are being hidden.
Upvotes: 1