Page_load not called in base class

A

Andy

Hi all,

I have a site with the following architecture:

Common.Web.dll - Contains a CommonPageBase class which inherits
System.Web.UI.Page
myadd.dll - Contains PageBase which inherits CommonPageBase
- Contains myPage which inherits PageBase

Each of these classes overrides OnInit and ties an event handler
(Page_load) to the Load event.

The problem is that the Page_Load event is NOT being called in the
PageBase class, although it is in in myPage and CommonPageBase. I can
even step through the code that assigns the event handerl in
PageBase... but the Page_Load is still never called (all Page_Loads are
private).

Any ideas?

Thanks
Andy
 
K

Kevin Spencer

another option is to call the base calss's Page_Load from the derived
class's Page_Load method.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
I'd rather be a hammer than a nail.
 
I

intrader

Reflection is used to find Page_Load, and the derived class' Page_Load is
hiding the base class'. I'd suggest having the base class override OnLoad.

-Brock
DevelopMentor
http://staff.develop.com/ballen
Brock, could you explain this further?
Who is using Reflection?
Which derived class is hiding the base class

I really appreciate your explanation

Thanks
 
K

Kevin Spencer

Brock, could you explain this further?
Who is using Reflection?
Which derived class is hiding the base class

I really appreciate your explanation

I'm going to assume, for the purpose of this discussion, that you're working
with VB.Net, and use VB.Net terminology.

You have created a base page class called "CommonPageBase" and wired up an
event handler ("Page_Load") to the "Load" event of the class, which inherits
from System.Web.UI.Page. Notice that System.Web.UI.Page does not define an
event handler for this event.

Next, you created a class called "Page_Base" which inherits "CommonPageBase"
and wired up an event handler called "Page_Load" to the "Load" event of the
class. Note that the base class already has a method called (named)
"Page_Load." Now, there are several ways of handling an inherited class
having a method defined with the same name as the name of a method in the
base class.

First, unless there is a difference in what the inherited class and what the
base class do in this method, there is no need to re-define it in the
inherited class; it inherits it. Any method in a base class that is defined
as Overrideable, Overrides, or MustOverride is available to (and, in fact,
already exists in) all derived classes of that class. Any method defined as
NotOverridable is not able to be overridden by derived classes. But it can
be re-defined. I'll get back to that shortly.

Overrideable indicates that a derived class may override (re-define) that
member.
Overrides indicates that the member overrides (re-defines) a member in a
base class that the base class inherits, and can therefore be overridden in
a derived class.
MustOverride indicates that an inherited class MUST re-define the member in
the base class.
NotOverridable indicates that an inherited class may NOT override the member
in the base class.

Now, when you create a method in an inherited class with the same name as a
method in the base class, this presents a problem to the compiler. The base
class has defined this method, and the derived class has defined a method
with the same name. So, how should the method (in this case) be executed
when called by name? There are several possibilities:

1. The base class can execute its definition of the method, and the derived
class can execute its definition of the method. Of course, the question then
becomes, which one executes first?
2. The derived class can execute its definition of the method, and the base
class can not.
3. The base class can execute its definition of the method, and the derived
class can not (not really possible).
4. The derived class can execute its definition of the method, and in doing
so, at a point of its own choosing, call the base class's implementation of
the same method.

Now, this dilemma is where the access modifiers (Overridable, MustOverride,
etc) come into play. These define the rules for deciding which of these
scenarios is selected.

If the method is overridable, the inherited class can define its
implementation of the method as "Overrides". This means that the base
class's implementation of the method will NOT be executed, unless the
derived class calls it directly (as in "MyBase.Page_Load()"). Note that the
derived class can call this base class method at any time, or not at all. In
fact, it can call the base class's implementation of that method from any
method in the derived class, as long as it is Public, Protected, Friend, or
Shared.

Now, if the method is not overridable, the derived class can actually, not
override it, but re-define it. This is what is referred to as "Shadowing" or
"Name-hiding." Generally, when you implement a method of the same name as a
base class method, in a derived class, and do not modify it with the Keyword
"Shadows," the program will compile, but the compiler will generate a
warning, to indicate that you have implicitly shadowed or hidden the member
of the same name in the base class. When a derived class hides or shadows a
method with the same name in a base class, the method is executed in the
derived class, but not in the base class, unless the derived class calls it
directly (as in "MyBase.Page_Load()"); Note that any method in a base class
may be shadowed (hidden) regardless of whether or not it is overridable.

I'm not sure why implicitly hiding or shadowing a member in a base class is
allowed. It often causes confusion, particularly in the cases of
inexperienced developers, or developers that are not using an IDE like
Visual Studio to create their apps, and cannot therefore see the
compiler-generated warning. But that is what Microsoft decided, for whatever
reasons. No doubt there was some discussion about it.

A bit more about shadowing: A method defined as "Shadows" does not have to
have the same signature (parameters and return type) as the method of the
same name in the base class. This is important, because of overloading.
Overloading is redefining a method with a different signature (parameters
and return type). Overloading a method in a base class, by changing its
signature, is not the same as Shadowing, or Name-hiding. So, if you overload
a method in a base class by creating a method with the same name and a
different signature, the base class's method is still available. It is
important to note this distinction, as there may be times when you want to
overload, and times when you may want to shadow, and it is best to do either
one intentionally!

So, if you define a method is a base class which you want to be Overridden,
it is best to define it as Overridable. You may then define the new version
of the method as Overrides. If you want a method to hide a member in the
base class, it is best to define it explictly as Shadows.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
I'd rather be a hammer than a nail.
 
A

Andy

Brock,

I know I could override OnLoad, but I'd really like to know whats going
on here. CommonBasePage's Page_Load event is called, as is myPage's
Page_Load (both named the same, but marked private. Reflection seems
to be able to tell which class defined each method just fine). Even if
i change the code in PageBase so that Page_Load is called LoadIt and
LoadIt is tied to the Load event, it still does not fire. So I don't
think its a case of reflection not being able to find the method,
because there is nothing called LoadIt defined anywhere else.

Andy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top