【.net 深呼吸】細說CodeDom(1):結構大觀


CodeDom 是啥東東?Html Dom聽過吧,XML Dom聽過吧。DOM一般可翻譯為 文檔對象模型,那 Code + DOM呢,自然是指代碼文檔模型了。如果你從來沒接觸過 CodeDom,你大概可以根據這個名字,推斷它應該和代碼文檔模型有關。

這推斷是靠譜的,CodeDom的功能,老周厚着臉皮把它歸結為兩大部分:

1、生成代碼文檔。這個聽起來很玄?不玄,就是咱們在VS里常常耍的代碼生成,比如你添加了一個服務引用,VS會幫你生成一個客戶端代理類。

2、動態編譯程序集。這個也好懂,就是動態編譯。

 

很多朋友一遇到這個就怕,很難,很復雜。其實不然,CodeDom並不難,把思路理清了就好學了,這個事咱們暫時不談,先說說老周要寫的這系列文章吧,簡單拋個磚,引個玉,免得大伙到時候向老周扔磚。

其實老周在幾個世紀前曾在其他的博客上寫過 CodeDom 相關的文章,大家也不要去人肉那些文章了,都是很膚淺很爛的文章,只是XX幾筆就寫完了,初學者朋友肯定看不懂的。沒辦法了,幾個世紀前老周的編程水平比較爛,有時候翻開自己以前寫的東西,都覺得很搞笑,自己當年怎么寫這么SB的文章。

為了讓更多朋友能夠看懂,也為了向傳統的編程教學方式發起挑戰,有關CodeDom這系列文章,老周計划開啟【廢話模式】,老周會盡可能進行細致的講解,到時候你不要覺得煩,廢話會很多的。正因為廢話多,所以一兩篇文章肯定寫不完的,至少得來個中篇小說的容量才行。

============================================

好,下面開始講廢話。

作為廢話系列的第一篇,老周不會馬上讓你動手寫代碼的,既然是跟代碼文檔有關的東西,那就先復習一下代碼的基礎知識,很重要的,趕緊划重點,期末考試一定會考的。我的大學老師在上復習課的時候,老喜歡說這句話。記得當年老周就是不划重點,所以考了48.5分,然后被抓去補考,補考考了66分,形式上不用重修,於是就天下大吉了。上大學時,老周對考試從來都沒認真過,包括考英語四級,作文里面還寫上粗口,不知道閱卷老師看到之后會不會血壓上升。

細細想一想,真不知道考試是為了什么,考60分又如何,考100分又如何,不還是一樣嗎。老周是出了名的上課不聽課,復習不認真,考試不重視,哪怕面對高考也一樣。但是老周絕不是不認真學習的人,只是跟賈寶玉差不多,怕看正經書,對於正經書以外的很多東西,老周反而很用功。

老周這個人,沒什么優點,長得不帥(眼睛小,嘴巴扁,鼻子高),又不富(當年那張中信銀行卡上時刻保持余額1.33元),1米78的身材也不高。唯一的優點就是興趣廣,愛好多,雜學旁收,從不客氣,只要別讓我讀教材做考試題就行。

所以當年有妹子就寫了一首詩來形容老周:

不愛煙酒不羡富,苦學逸少子昂書。

酷喜上課看雜志,最怕臨考背試題。

偶得仙樂歌一闕,沉思漫筆有洞天。

 

CodeDom支持如C#、VB、C++、JScript這幾種語言的代碼生成,當然,必須是生成CLR能認識的代碼,所以這里頭的C++主要是托管C++。

現在,你開始回憶一下,滿懷深情地回憶一下,一個CLR程序集里面有什么?由於在VS里面,一個項目就是一個程序集,或者你可以想一下,一個項目的代碼里面有啥。

咱們從外向里一層一層的刷一下。

A、一個項目中是不是有N個命名空間?想起來了吧,而命名空間里面可以包括命名空間,不過,CodeDom中不使用嵌套命名空間,比如,System和System.IO可以認為是兩個單獨的命名空間。

B、然后,大伙再想想,一個命名空間下有啥。類型,好,類型又有多少種?數一數,類、結構、枚舉、接口、委托。

C、類型下面有什么?對,成員,那么類型成員有幾種。再數一數,構造函數、字段、屬性、方法、事件。

     1)如果類型是泛型類型,還會包含若干泛型列表,泛型參數可能還帶有約束。

     2)如果成員是方法,會包含有輸入參數、輸出參數或返回值;對於屬性成員,會有get和set訪問器。對於索引器,會有索引變量。

D、類型成員下包含語句集合(Statement),通常翻譯為語句比較好聽。常規代碼語句以英文的分號(;)結束,這個大家都很熟悉了,當然,像if、while、for這些語句比較特別,它們往往包含多個條件。

E、語句是由表達式和運算符(操作符)組成。

比如,這樣就是一個表達式,常量表達式。

300

這樣就是一個語句,賦值語句。

k = 300;

這是語句,它包括一個 = 運算符(賦值運算符),一個變量引用表達式(k),以及一個常量表達式(300)。

 

有一個語句大家要注意,就是這樣:

double x = 0.0021d;

別看它很簡單,別看它是很基礎的知識,這里面的門道你還真未必已經掌握。

它是一個復合語句,其實它包含兩個語句:聲明語句(double x;),賦值語句(x = 0.0021d)。如果拆開來,可以這樣寫。

double x;
x = 0.0021d;

而 double x = 0.0021d 是在變量聲明時順便進行初始化。在兩種寫法在 CodeDom 代碼生成中是應當區別,這個后續的文章中老周會講的,現在你暫時了解一下。

 

好,代碼的結構大觀我們復習完了,老周保證你期末考試能考95分。

既然是要講CodeDom的,就得把代碼結構中的各個對象與CodeDOM類型對號入座,這樣可以方便大家熟悉CodeDom模型。

來,先喝杯牛奶,做好准備,下面開始接觸 CodeDom了。

 

=========================================

CodeDom 的根容器是 CodeCompileUnit,它是一個編譯單元,這個類你必須認識,不然以后就無法CodeDom了,如果要進行動態編譯,就應該用一個編譯單元來編譯,不能用一句代碼來編譯,因為這樣生成的程序沒有實際意義,也不能運行。

編譯單元你可以把它類比一個VS項目,一個程序集。所以,你會看到,CodeCompileUnit 類有一個 Namespaces 屬性,這使得一個編譯單元可以包含 N 個命名空間。

一個命名空間可以用 CodeNamespace 類來表示,Comments 用來設置給命名空間寫的注釋,Imports就是這個命名空間中要引入的其他命名空間,就是C#中的 using,VB中的 Import,托管C++中的 using。

一個 CodeNamespace 類公開了 Types 屬性,表示某個命名空間下的類型集合。要聲明一個類型,使用 CodeTypeDeclaration 類,至於定義的是類,是接口,還是枚舉,可以用類的屬性來決定。例如IsInterface指定是否為接口,IsClass指定是否為類,IsEnum指定是否為枚舉等。如果類是從其他類型派生的,或者實現接口,那可以向BaseTypes屬性添加基類型。如果基類是Object,可以忽略。

但是,委托類型的聲明比較特殊,它使用 CodeTypeDelegate 類。

一個類型之下包含的是類型成員,它們對應的CodeDom類有:CodeMemberField(字段)、CodeMemberProperty(屬性)、CodeMemberMethod(方法)、CodeMemberEvent(事件)。

注意,表示類型構造函數有兩個類。如果是靜態構造函數,因為它是屬於類型而非實例,所以要用 CodeTypeConstructor;對於普通面向實例的構造函數要使用 CodeConstructor。

 

好了,今天就講到這里吧,講多了,大伙會接受不了。下一篇文章,老周再介紹代碼表達式和代碼語句。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM