ASP.NET 2.0的Eval方法揭秘解讀

來源:互聯網
上載者:User

   實際上Eval方法是TemplateControl的,而System.Web.UI.Page和System.Web.UI.UserControl都繼承於TemplateControl,所以我們可以在Page和UserControl上直接調用個方法。   
    
     Page.Eval方法可以協助我們更好的撰寫資料繫結運算式,在ASP.NET   1.x時代,資料繫結運算式的一般形式是:   
 

 <%# DataBinder.Eval(Container,“DataItem.Name”)   %>        而在ASP.NET   2.0中,同樣的代碼,我們可以這樣寫:   Code
<%# Eval(“Name”)%>   
     ASP.NET   2.0是怎麼實現的呢?我們先從Eval方法來研究,通過反射.NET  fromwork   2.0類庫的原始碼,我們可以看到這個方法是這樣實現的:   protected   internal   object   Eval(string   expression)   
{   
     this.CheckPageExists();   
     return   DataBinder.Eval(this.Page.GetDataItem(),   expression);   
}        第一行我們不必管,這是檢查調用的時候有沒有Page對象的,如果沒有則會拋出一個異常。   關鍵是第二行:     return   DataBinder.Eval(this.Page.GetDataItem(),   expression);         Page.GetDataItem()也是2.0中新增的一個方法,用途是正是取代ASP.NET   1.x中的Container.DataItem。   
     看來不摸清楚GetDataItem()方法,我們也很難明白Eval的原理。GetDataItem的實現也很簡單: public   object   GetDataItem()   
{   
     if   ((this._dataBindingContext ==  null) || (this._dataBindingContext.Count == 0))   
     {   
           throw   new   InvalidOperationException(SR.GetString("Page_MissingDataBindingContext"));   
     }   
     return   this._dataBindingContext.Peek();   
}   
   
     我們注意到了有一個內部對象_dataBindingContext,通過查原始碼發現這是一個Stack類型的東西。所以他有Peek方法。而這一段代碼很容易看懂,先判斷這個Stack是否被執行個體化,然後,判斷這個Stack裡面是不是有任何元素,如果Stack沒有被執行個體化或者沒有元素則拋出一個異常。最後是將這個堆棧頂部的元素返回。   
     ASP.NET   2.0用了一個Stack來儲存所謂的DataItem,我們很快就查到了為這個堆棧壓元素和彈出元素的方法:Control.DataBind方法:  protected   virtual   void   DataBind(bool   raiseOnDataBinding)   
{   
      bool   flag1   =   false;//這個標誌的用處在上下文中很容易推出來,如果有DataItem壓棧,則在後面出棧。   
       if(this.IsBindingContainer)//判斷控制項是不是資料繫結容器,實際上就是判斷控制項類是不是實現了INamingContainer   
      {   
          bool   flag2;   
          object   obj1   =   DataBinder.GetDataItem(this,   out   flag2);//這個方法是判斷控制項是不是有DataItem屬性,並把它取出來。   
           if   (flag2   &&   (this.Page   !=   null))//如果控制項有DataItem   
         {   
            this.Page.PushDataBindingContext(obj1);//把DataItem壓棧,PushDataBindingContext就是調用_dataBindingContext的Push方法   
              flag1   =   true;   
         }   
      }   
      try   
      {   
          if   (raiseOnDataBinding)//這裡是判斷是不是觸發DataBinding事件的。   
           {   
             this.OnDataBinding(EventArgs.Empty);   
          }   
         this.DataBindChildren();//對子控制項進行資料繫結,如果這個控制項有DataItem,則上面會將DataItem壓入棧頂,這樣,在子控制項裡面調用Eval或者GetDataItem方法,就會把剛剛壓進去的DataItem給取出來。   
      }   
     finally   
     {   
         if(flag1)//如果剛才有壓棧,則現在彈出來。   
          {   
            this.Page.PopDataBindingContext();//PopDataBindingContext就是調用_dataBindingContext的Pop方法   
          }   
     }   
  }   

  
     至此,我們已經可以完全瞭解ASP.NET   2.0中GetDataIten和Eval方法運作的原理了,下一次我打算研究ASP.NET   2.0中的新的Bind文法。   
    
     有提供Bind文法資料的和提出好建議的酌情給分,up、頂等分會很少,接分者無分。 

     關於效率:     毋庸置疑的是強型別轉換Container的效率是最高的,Eval最終是調用DataBinder.Eval方法,DataBinder.Eval是採用反射來擷取資料的,這顯然不如強型別資料轉換。        我們可以比較一下各種方法:   
    ((Type)   Container.DataItem).Property   
     這種方法效率是最高的,因為不存在任何反射。   
    
     其次是:    ((Type)   GetDataItem()).Property   
     這種方法效率差的原因在於多了一個Stack的Peek操作,當然,實際上這點兒差別可以忽略。   
    
     最後是:    Eval或者DataBinder.Eval,這兩種方法都使用反射來尋找屬性或者索引器成員,效率大打折扣。   
    
     另外一個值得注意的問題是,所有實現了INamingContainer介面的Control,都應該實現IDataItemContainer介面,因為在Control.DataBind的時候,如果發現控制項實現了INamingContainer介面,就會試圖去尋找它的DataItem,如果這個控制項沒有實現IDataItemContainer,則DataBinder.GetDataItem方法會使用反射看看控制項有沒有一個叫做DataItem的屬性成員,顯然這不是我們希望看到的。        其實ASP.NET還有一個標記介面:INonBindingContainer,實現了INamingContainer介面的控制項可以選擇同時實現這個來命令ASP.NET不去尋找DataItem,可是很可惜,不知道微軟出於什麼目的,這個介面是internal的……   
    
     其實效率方面不必太重視了,Eval運算式很好看的,即使有那麼極端的重視效率,GeDataItem也是不錯的選擇。毋庸置疑的是強型別轉換Container的效率是最高的,Eval最終是調用DataBinder.Eval方法,DataBinder.Eval是採用反射來擷取資料的,這顯然不如強型別資料轉換。   
    原文地址:http://blog.sdtv.com.cn/user1/11/1815.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.