2004 8 18 對構架 窗體 編譯的認識

2021-09-05 15:01:13 字數 3369 閱讀 7823

0.推薦看的一本書《essential asp.net with examples in c#/asp.net基礎教程-c#案例版》

這本書的內容大多涉及到一些底層的細節,對一些具體技術的講解也是「高屋建瓴」的那種,對增強對.net的整體把握很有好處,本文的知識大部分來自這本書。

當然這本書還有vb.net版,要注意的是,不要被這本書的中文譯名給騙了,essential是什麼意思,大家心裡都有數,不知道譯者當初是怎麼想的……

1.編譯與解釋

請求乙個傳統的asp頁面,對網頁中的文字進行線形解析,提取所有不是伺服器端指令碼的內容,並作為響應返回,而網頁中的伺服器端指令碼首先通過乙個合適的直譯器(jscripe或vbscript)解釋執行,執行結果作為響應返回。相反,asp.net網頁始終被編譯成.net類,並儲存在程式集中。第一次訪問網頁所需的開銷包括:載入asp.net工作者程序,對.aspx檔案進行語法分析,並將它編譯成乙個程式集。以後訪問就只需執行已編譯的**即可。

2.**隱藏技術

假設有一名為pagemodel的asp.net網頁,命名空間beginner。

當不使用**隱藏技術時,整個程式就是乙個.aspx檔案,在編譯時生成的類是直接繼承自system.web.ui.page,並且屬於asp命名空間下,即asp.pagemodel_aspx。

但如果使用了**隱藏技術,則整個程式包括乙個.aspx檔案和乙個.cs檔案(假設是用c#),在編譯時先編譯.cs檔案,然後再編譯.aspx檔案。.cs檔案當然是直接編譯成beginner.pagemodel,該類繼承自system.web.ui.page,然後輪到.aspx檔案,這時編譯生成的類是繼承自beginner.pagemodel,也就是說.cs檔案編譯生成的類起到了乙個橋梁的作用。

由此可見,**隱藏是一種建立中間基類的技術。使用這種技術,可以向**隱藏類中新增字段、方法和事件處理方法,並可以讓那些根據.aspx檔案建立的類繼承這些特性。

3.指令碼塊和指令碼標記

當不使用**隱藏時,可以在指令碼塊和指令碼標記裡對頁面進行操作,典型的指令碼塊和指令碼標記的例子為:

<%

response.write(this.gettype());

%>

注意在指令碼塊和指令碼標記裡放置的**,將被放入生成的類定義中,而這兩個地方是完全不同的。位於指令碼塊()內的**,是直接放到類的定義中,而位於指令碼標記(<%

%>)之內的**,將放入類的乙個方法主體中,這個方法類似於control類裡的render方法,在生成網頁時呼叫該方法把指令碼標記內的**輸出。

4.控制項的宣告

當不使用**隱藏時,在.aspx頁面中直接用標記放置乙個伺服器控制項就可以使用,也可以在**塊中操作它的屬性,但是不能在指令碼塊中宣告該控制項,那將產生重複宣告的錯誤,典型的錯誤提示為「類「asp.pagemodel_aspx」已經包含了「x」的定義」。這是因為在編譯生成的類中,會自動為用標記宣告的控制項產生乙個受保護的字段用來標識該控制項。

但使用**隱藏時,在.aspx檔案中插入乙個伺服器控制項後,還可以在.cs檔案中宣告該控制項,並進行操作,這樣做不會產生重複宣告的錯誤。

首先要明白的是,在.cs檔案中宣告的控制項,其識別符號必須與.aspx檔案中的控制項的識別符號相同,這個不難理解,因為上面我們已經知道,.aspx生成的類繼承自.cs檔案生成的類,如果識別符號不同,那將不能進行正確的操作。

在.aspx檔案進行解析的過程中,解析器使用反射技術查詢**隱藏基類。如果在**隱藏基類中查到與伺服器端控制項識別符號相匹配的字段,則不管它是公有的還是受保護的字段,都不會在生成的類中為該控制項建立乙個字段。如果在**隱藏基類中找不到這樣的字段,才會在新生成的類中建立乙個這樣的字段。用這種辦法來保證所有的伺服器控制項,不管是從**隱藏基類繼承而來的,還是直接在生成的類中宣告的,都在生成的類中有乙個相應的字段。

5.查詢編譯生成的檔案

假設系統盤為c,則找到這些編譯後的檔案的方法是先進入c:\windows\microsoft.net\framework\v1.1.4322\temporary asp.net files,其中v1.1.4322這個目錄是我的機器上的目錄,該目錄是.net framework的版本號(?),進入後會發現一些以你設定的虛擬目錄命名的資料夾,確定其中的乙個,一直點下去,就會發現那些編譯過的檔案。可以用vs.net配合roeder's .net reflector檢視其細節。

6.配合編譯檔案檢視細節

現在我們找到這些編譯了的檔案了,可以配合他們來複習一下上面的知識。

先來看上面的那個沒有使用**隱藏技術的頁面,檔名為s.aspx,它的部分編譯後的類**如下:

b0fgdgkv.0.cs

//命名空間為asp

namespace asp

......

//這個方法用來裝在指令碼標記內的**

private void __render__control1(system.web.ui.htmltextwriter __output, system.web.ui.control parametercontainer) {

......

//在指令碼標記內的**

response.write(this.gettype());

......

再來看乙個使用了**隱藏技術的,該檔名sp_dr2.aspx和sp_dr2.aspx.cs,命名空間是startmssql,其中.aspx檔案編譯後的類的部分**如下:

zti43wya.0.cs

//命名空間為asp

namespace asp {

//繼承自

startmssql.sp_dr2

public class sp_dr2_aspx : startmssql.sp_dr2, system.web.sessionstate.irequiressessionstate {

......

另外,通過使用roeder's .net reflector,從基本的物件樹也可看出這種關係。特別的,當你檢視sp_dr2類時,會發現base types是system.web.ui.page,而derived types則是asp.sp_dr2_aspx,而檢視zti43wya.dll時,base types為startmssql.sp_dr2

其他的一些細節大家可以自己動手找找 :)

這篇筆記可以整理出來,還得謝謝昨天晚上東方的那個問題。昨晚我回宿舍後又翻了翻essential

這本書,今上午過來後把那些編譯檔案找出來研究,這才讓自己明白了一些。文章裡面肯定還有不對的地方,請高手指教。

另外最後再提兩個問題,希望可以得到高手的解答 :)

a.目錄c:\windows\microsoft.net\framework\v1.1.4322\temporary asp.net files中,v1.1.4322是不是.net framewok的版本號?

b.不使用**隱藏技術時的乙個.aspx檔案,編譯完成後的檔案-比如.dll-是直接放到以虛擬目錄命名的資料夾裡,而不是和專案的整個.dll檔案整合?

對編譯原理的看法

編譯原理是計算機專業的一門重要專業課,旨在介紹編譯程式構造的一般原理和基本方法。內容包括語言和文法 詞法分析 語法分析 語法制導翻譯 中間 生成 儲存管理 優化和目標 生成。編譯原理是計算機專業設定的一門重要的專業課程。雖然只有少數人從事編譯方面的工作,但是這門課在理論 技術 方法上都對學生提供了系...

對編譯原理的理解

編譯原理就是什麼?在我看來,編譯原理就是將高階語言翻譯成計算機語言 即計算機所能識別的二進位制 所遵循的規律,並且讓你理解機器是如何理解高階語言的。學習編譯原理有什麼好處?當你真正完成編譯原理的學習後,你對你所寫的程式 程式語言都會有更深的本質認識,這樣的認識也會讓你站的高度完全不同,並且知道編譯的...

對編譯原理的認識

1 編譯原理就是什麼?通過網上學習,我深刻的認識到編譯原理是編譯技術的基本理論和實現技術,是計算機專業的一門重要專業課,旨在介紹編譯程式構造的一般原理和基本方法。內容包括語言和文法 詞法分析 語法分析 語法制導翻譯 中間 生成 儲存管理 優化和目標 生成。從源語言提取需要的資訊,把源語言翻譯成目標語...