2013-04-05 2 views
1

В существующем приложении ASP.NET, у меня есть базовый класс, содержащий метод Page_Load:Несколько методов 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 в ее жизненном цикле в такой ситуации? Какой из них называется? Или их обоих называют?

Примечание: Я знаю, что это плохой дизайн, я не уверен, что имел в виду автор оригинала, я просто пытаюсь понять, что происходит, и как это повлияет на логику системы.

+1

Некоторые точки останова и отладка ответят на ваш вопрос. – melancia

ответ

1

После некоторого копания я узнал, что происходит.

Короткий ответ: только самый верхний метод называется!

Сначала я поставил некоторые точки останова, такие как MelanciaUK, предлагаемые в комментарии. Это показало мне, что вызывается только самый верхний метод.

Копаем глубже, я посмотрел, что предложил волпав. Верно, что AutoEventWireup было установлено значение true, что автоматически подключало метод к обработчику событий (так как это действительно не было сделано вручную). Однако, в отличие от того, что он утверждал, вызывался только метод top Page_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 и один с декларированием type PageBaseClass.

Я, хотя это вызовет проблемы для второго вызова, так как у меня есть два результата, я ожидал, что он выкинет AmbiguousMatchException. Однако этого не произошло. Он содержал MethodInfo для метода в ActualPage.

Копаем глубже, я наткнулся на статью К. Скотт Аллен: Внутри 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, возвратил этот метод.

Похоже, что если метод события автоматически подключается к сети, он не будет подключать какие-либо методы, которые скрываются.

+0

Рад, что вы поняли, и спасибо, что доказали мне, что не так ;-) – volpav

0

Код в обоих методах будет вызываться, поскольку они по существу являются обработчиками событий (которые привязаны базовым классом, другим - вашим классом «ActualPage»). Это связано с тем, что свойство «AutoEventWireup» установлено на «true» (оно установлено по умолчанию в вашей разметке).

Связанные вопрос о «AutoEventWireup»: What does AutoEventWireUp page property mean?

UPDATE

Оказалось, что я был неправ о том, что оба метода будет называться и на самом деле, один объявлен на «ActualPage» вызывается только , См. Ответ Рене ниже.

Смежные вопросы