既然叫“深入淺出”了,那我們先來深一下,好吧?
一、用到了哪些命名空間?
說白了,基本上與代碼生有關的類都在System.CodeDom命名空間和System.CodeDom.Compiler。不知道各位對這兩個命名空間熟悉指數是多少?
二、CodeDomProvider類
該類位於System.CodeDom.Compiler命名空間下,它是一個抽象類別,有朋友可以疑問了,這……這是個抽象類別,那是不是不能new執行個體?是D。
既然是抽象類別,那麼一定有子類來實現它的,那麼實現CodeDomProvider的子類在哪?哈,那個類在Microsoft.CSharp命名空間下,叫CSharpCodeProvider,不信?看看下面的圖片。
如果還不信,來,你建立一個控制台應用程式,然後執行以下代碼,看看結果是啥?
var cpr = CodeDomProvider.CreateProvider("C#"); Console.WriteLine(cpr.GetType().ToString());
大家都看到了,CodeDomProvider是通過調用靜態方法CreateProvider來建立執行個體,其中的字串參數就是語言的名字,如“C#”,用“cs”、“CSharp”都可以。
那麼,如果要產生的程式碼是VB.NET,那麼它調用CreateProvider方法後又返回了什麼呢?請看下面的代碼。
var cpr = CodeDomProvider.CreateProvider("VB"); Console.WriteLine(cpr.GetType().ToString());
呵呵,再執行一下,看看有什嗎?這次不用我介紹了吧。
為什麼要介紹CodeDomProvider類,因為它太重要了,它相當於“孕婦”,要產生的程式碼相當於“待出生的孩子”,嗯,有這個比喻,你大致明白它的用途了,對啊,我們要產生代碼,就是要用到它的N個方法,比如:
(1)GenerateCodeFromCompileUnit:從CodeCompileUnit產生代碼;
(2)GenerateCodeFromExpression:從CodeExpression產生代碼;
(3)GenerateCodeFromMember:從CodeTypeMember產生代碼;
(4)GenerateCodeFromNamespace:從CodeNamespace產生代碼;
(5)GenerateCodeFromStatement:從CodeStatement產生代碼;
(6)GenerateCodeFromType:從CodeTypeDeclaration產生代碼。
這些方法就不介紹了,開啟“物件瀏覽器”就看到了。
接下來要說上面幾個方法中出現幾位新“哥們”,其實你發現上面那堆方法都是兄弟,看著都像。上面提及的那堆東西都在System.CodeDom命名空間下。
三、CodeCompileUnit類
該類派生自CodeObject類,屬於CodeDom文檔對象。CodeCompileUnit可以稱為一個“代碼單元”,是一個容器,但是,貌似理論上的東西不好理解,但我們看到,CodeCompileUnit類可以包含程式集特性,也可以包含其它程式集的引用集合,包含N個命名空間,或者,我們可以把它理解為一個程式集。
四、CodeNamespace類
看名字就知道這個傢伙是幹哪行的。它表示代碼中的命名空間,Imports屬性工作表示要引入的命名空間,如C#中的using System。Types屬性包括命名空間中定義的類型集合,如類、結構等。
五、CodeExpression類
這是代碼錶達式的基類,如a = b;
六、CodeStatement類
代碼描述的基類,代碼描述塊包括多個運算式,在C#中可以理解為{和}之間的語句。
七、CodeTypeMember類
提供類型成員的基類,如方法、屬性、事件等。
八、CodeTypeDeclaration類
表示類、結構、介面或枚舉等聲明。如
public class A { }
好了,看看上面的內容,深不深?大家覺得?哈哈,還是有點枯燥,這樣吧,下面我們來“淺”一下哦。
=> 如何組建定義命名空間的代碼
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.CodeDom;using System.CodeDom.Compiler;namespace SampleApp{ class Program { static void Main(string[] args) { // 定義命名空間的CodeDom對象 CodeNamespace MyNameSpace = new CodeNamespace("MyApplication"); // 建立代碼產生提供對象 Console.Out.WriteLine("\n--------- 以下是C#代碼 ------------"); // C# CodeDomProvider CSProvider = CodeDomProvider.CreateProvider("C#"); CSProvider.GenerateCodeFromNamespace(MyNameSpace, Console.Out, new CodeGeneratorOptions { BracingStyle = "C" }); Console.Out.WriteLine("\n\n------- 以下是VB.NET代碼 -----------"); // VB CodeDomProvider VBProvider = CodeDomProvider.CreateProvider("VB"); VBProvider.GenerateCodeFromNamespace(MyNameSpace, Console.Out, new CodeGeneratorOptions()); Console.ReadKey(); } }}
上面代碼中,調用CodeDomProvider的GenerateCodeFromXXX方法時,其中第三個參數為一個CodeGeneratorOptions對象,它用作代碼產生的選項,BracingStyle屬性工作表示C#中大括弧的樣式,有兩個值“C”表示大括弧都佔一行;“Block”則不是。看看下面兩張圖就明白了。
好,現在看看上面的代碼執行後是啥結果。