当前位置:编程学习 > C#/ASP.NET >>

一个关于Page_load诡异的问题!

如果我们按照Page_Load()去调用一样可以成功。代码如下:

    protected void Page_Load()
    {
        Response.Write("load1");

    }

输出:load1

如果现在我们加上一个(page小写)
    protected void page_Load()
    {
        Response.Write("load2");

    }

结果输出:load2,也就是后面的函数覆盖了前面的。

我们再换下:

    protected void Page_Load(object sender, EventArgs e) 
    {
        Response.Write("load1");

    }
    protected void page_Load()
    {
        Response.Write("load2");

    }
应该输出什么,没错,又输出了load1;诡异之处,有两点:

1:不加(object sender, EventArgs e) 这两个参数,一样可以输出。

2:但是如果两个函数,一个加参数,一个不加,加的将覆盖不加的。后面将覆盖前面的。


同样的,对于 Page_preload()一样。

而且,用reflector反编译,你会发现,Page里面竟然没有load事件的定义。是有preLoad的定义。

更诡异的是,上述例子用VB竟然都通不过。


--------------------编程问答-------------------- 等待高手来讲其原由! --------------------编程问答-------------------- 以下抄自msdn  

如果页面想要处理某个事件,它应该显式地注册相应的处理程序。然而,为了向后兼容早期的 Visual Basic 编程风格,ASP.NET 也支持一种隐式的事件挂起形式。在默认情况下,页面将尝试把特定的方法名与事件匹配起来;如果找到匹配的方法,就认为该方法是该事件的处理程序。ASP.NET 提供了六个方法名的特定识别。它们是 Page_Init、Page_Load、Page_DataBind、Page_PreRender 和 Page_Unload。这些方法被当作是 Page 类所提供的相应事件的处理程序。HTTP 运行时将自动把这些方法与页面事件绑定起来,这样一来,开发人员就不必编写所需的粘接代码。例如,名为 Page_Load 的方法与页面的 Load 事件绑定,就像已编写以下代码一样。

this.Load += new EventHandler(this.Page_Load);

在页面级上,以上所列的某些阶段是不可见的,并仅影响服务器控件编写者和那些凑巧要创建从 Page 派生的类的开发人员。页面向外界发送的活动信号仅包括 Init、Load、PreRender、Unload 以及嵌入式控件所定义的所有回发事件。

--------------------编程问答-------------------- 函数的重载引起的。 --------------------编程问答--------------------
“为了向后兼容早期的 Visual Basic 编程风格”但这个例子在VB中通不过。

如果两个函数,一个加参数,一个不加,加的将覆盖不加的。那又是为什么呢?



但是 protected void Page_Load(obejct sender) 
    { 
        Response.Write("load1"); 

    } 

就不过输出load1

protected void Page_Load() 

就 可以。 --------------------编程问答-------------------- 这么心细 --------------------编程问答-------------------- ddd --------------------编程问答-------------------- hh --------------------编程问答-------------------- 先看看调用栈如下所示:

> WebApplication1.DLL!WebApplication1._Default.page_load() Line 24 C#
  System.Web.RegularExpressions.dll!System.Web.Util.CalliHelper.ArglessFunctionCaller(System.IntPtr fp, object o) + 0x9 bytes
  System.Web.dll!System.Web.Util.CalliEventHandlerDelegateProxy.Callback(object sender, System.EventArgs e) + 0x36 bytes
  System.Web.dll!System.Web.UI.Control.OnLoad(System.EventArgs e) + 0x74 bytes
  System.Web.dll!System.Web.UI.Control.LoadRecursive() + 0x32 bytes

> WebApplication1.DLL!WebApplication1._Default.Page_Load(object sender = {ASP.default_aspx}, System.EventArgs e = {System.EventArgs}) Line 15 C#
  System.Web.RegularExpressions.dll!System.Web.Util.CalliHelper.EventArgFunctionCaller(System.IntPtr fp, object o, object t, System.EventArgs e) + 0xf bytes
  System.Web.dll!System.Web.Util.CalliEventHandlerDelegateProxy.Callback(object sender, System.EventArgs e) + 0x24 bytes
  System.Web.dll!System.Web.UI.Control.OnLoad(System.EventArgs e) + 0x74 bytes
  System.Web.dll!System.Web.UI.Control.LoadRecursive() + 0x32 bytes

问题就在CalliEventHandlerDelegateProxy.Callback这个函数这里,调用这个函数首先应该实例化CalliEventHandlerDelegateProxy对象,这个对象是在哪实例化的?

这个对象是在页面的基类TemplateControl中的HookUpAutomaticHandlers方法被实例化的,这个方法最终决定调用哪个Load方法,代码如下:


    

    internal void HookUpAutomaticHandlers() { 
        // Do nothing if auto-events are not supported 
        if (!SupportAutoEvents) {
            return; 
        }

        // Get the event list for this Type from our cache, if possible
        object o = _eventListCache[GetType()]; 

        IDictionary dictionary = null; 
 
        // Try to find what handlers are implemented if not tried before
        if (o == null) { 
            lock (_lockObject) {

                // Try the cache again, in case another thread took care of it
                o = _eventListCache[GetType()]; 

                if (o == null) { 
                    dictionary = new ListDictionary(); 

                    GetDelegateInformation(dictionary); 

                    // Cannot find any known handlers.
                    if (dictionary.Count == 0) {
                        o = _emptyEventSingleton; 
                    }
                    else { 
                        o = dictionary; 
                    }
 
                    // Cache it for next time
                    _eventListCache[GetType()] = o;
                }
            } 
        }
 
        // Don't do any thing if no known handlers are found. 
        if (o == _emptyEventSingleton) {
            return; 
        }

        dictionary = (IDictionary)o;
 
        foreach (string key in dictionary.Keys) {
            EventMethodInfo info = (EventMethodInfo)dictionary[key]; 
 
            Debug.Assert(_eventObjects[key] != null);
 
            bool eventExists = false;
            MethodInfo methodInfo = info.MethodInfo;

            Delegate eventDelegates = Events[_eventObjects[key]]; 
            if (eventDelegates != null) {
                foreach (Delegate eventDelegate in eventDelegates.GetInvocationList()) { 
                    // Ignore if this method is already added to the events list. 
                    if (eventDelegate.Method.Equals(methodInfo)) {
                        eventExists = true; 
                        break;
                    }
                }
            } 

            if (!eventExists) { 
                // Create a new Calli delegate proxy 
                IntPtr functionPtr = methodInfo.MethodHandle.GetFunctionPointer();
                EventHandler handler = (new CalliEventHandlerDelegateProxy(this, functionPtr, info.IsArgless)).Handler; 

                // Adds the delegate to events list.
                Events.AddHandler(_eventObjects[key], handler);
            } 
        }
    } 


--------------------编程问答-------------------- 楼上强人!

请问楼上是如何得到调用栈的代码的呢?


还有HookUpAutomaticHandlers的代码是如何找到的?
--------------------编程问答-------------------- 按照这么说,c#的运行效率似乎还不如VB,VB是直接进行代理handers me.load的 --------------------编程问答-------------------- 不知所云?!
protected void Page_Load(object sender, EventArgs e) 这是本身
    { 
        Response.Write("load1"); 
        page_Load();
    } 
    protected void page_Load() 这是自定义
    { 
        Response.Write("load2"); 

    } 
--------------------编程问答--------------------
引用 11 楼 xianfajushi 的回复:
不知所云?!
protected void Page_Load(object sender, EventArgs e) 这是本身
    {
        Response.Write("load1");
        page_Load();
    }
    protected void page_Load() 这是自定义
    {
        Response.Write("load2");

    }


是啊,但是你把第一个函数去掉,它一样可以运行Response.Write("load2");啊 --------------------编程问答-------------------- 楼上强人! 

请问楼上是如何得到调用栈的代码的呢? 


还有HookUpAutomaticHandlers的代码是如何找到的? 
 
 
补充:.NET技术 ,  ASP.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,