日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

動(dòng)態(tài)生成與編譯(四)----用CodeDOM生成一個(gè)完整的類(上)

 家住天地 2010-09-06

動(dòng)態(tài)生成與編譯(四)----用CodeDOM生成一個(gè)完整的類(上)

 

 

()里用一個(gè)求Fibonacci數(shù)列的程序來(lái)說(shuō)明CodeDOM是如何生成一些程序的基本語(yǔ)句的?,F(xiàn)在寫(xiě)程序很少會(huì)直接寫(xiě)幾個(gè)方法來(lái)讓Main()從頭調(diào)到尾的,總是要用幾個(gè)類來(lái)封裝封裝的。

CodeDOM里一個(gè)類的字段、屬性、事件(講到事件,委托總是逃不了的)、方法等又是如何來(lái)生成的呢?上次只講到了類方法(CodeMemberMethod),在CodeTypeMember這個(gè)重量級(jí)的類下面還有很多沒(méi)有涉及,這次用一個(gè)比較完整的類來(lái)講余下的部分。

 

開(kāi)始部分的幾下CodeCompileUnit、CodeNamespace、CodeNamespaceImport都是一樣的,就不多說(shuō)了。

聲明一個(gè)名為DemoClass的類:

CodeTypeDeclaration MyClass = new CodeTypeDeclaration("DemoClass");

對(duì)一個(gè)Class來(lái)說(shuō)除了名字外也沒(méi)什么好設(shè)置的,一般情況下這樣就行了。但有些定義了一些Attribute的要麻煩一點(diǎn)。要對(duì)MyClassCustomAttributes屬性進(jìn)行設(shè)置(不是MyClassAttributes這個(gè)屬性,這個(gè)是設(shè)置可見(jiàn)性的)。

對(duì)于Attribute的生成CodeDOM有專門(mén)的類來(lái)實(shí)現(xiàn),就是CodeAttributeDeclaration。如要對(duì)DemoClass這個(gè)類加一個(gè)[Description("CodeDOM自動(dòng)生成的一個(gè)類")]這樣的Attribute可以這樣寫(xiě):

                MyClass.CustomAttributes.Add(new CodeAttributeDeclaration("Description",new CodeAttributeArgument(

                 new CodePrimitiveExpression("CodeDOM自動(dòng)生成的一個(gè)類"))));

從上可以看到CodeAttributeDeclaration的構(gòu)造函數(shù),第一個(gè)參數(shù)是Attribute的名,第二個(gè)參數(shù)是Attribute的參數(shù)。對(duì)Description來(lái)說(shuō)參數(shù)是“CodeDOM自動(dòng)生成的一個(gè)類”這么一個(gè)字符串。當(dāng)然不能直接用這個(gè)字符串來(lái)當(dāng)構(gòu)造函數(shù)的參數(shù)。對(duì)于Attribute的參數(shù)又有一個(gè)專門(mén)的類的――CodeAttributeArgument,真是麻煩。還要把字符串包成一個(gè)CodeExpression去當(dāng)CodeAttributeArgument的構(gòu)造函數(shù)的參數(shù)才算了結(jié)。(最后那個(gè)CodePrimitiveExpression在(三)里講到過(guò)了,它返回一個(gè)原始的表達(dá)式,實(shí)際上就是把括號(hào)里的東西類型轉(zhuǎn)換成一個(gè)CodeExpressoin)。

 

(上面的長(zhǎng)長(zhǎng)的一句就是在寫(xiě)CodeDOM程序時(shí)構(gòu)造函數(shù)連用的寫(xiě)法。當(dāng)然你也可以不用這種new串聯(lián)的寫(xiě)法,可以從最里層開(kāi)始聲明一個(gè)個(gè)的變量一句句的構(gòu)造出來(lái)。上面一句就是分為四句了,不過(guò)這樣寫(xiě)變量一多自己也要暈掉,所以一般不是太長(zhǎng)的我還是喜歡連寫(xiě),如果把代碼格式編排一下一般寫(xiě)10個(gè)new是沒(méi)什么問(wèn)題的。比較頭痛的是在VS.NET中排好的格式到Word里會(huì)變掉)

 

好,一個(gè)類聲明好了,下面對(duì)類里的元素一個(gè)一個(gè)來(lái)說(shuō)。

先是字段Field,從它的類層次結(jié)構(gòu)里能看出,這個(gè)肯定是用CodeMemberField來(lái)做的,如在類里聲明

private int myField;

可以這樣來(lái)寫(xiě):

                CodeMemberField myField = new CodeMemberField("System.Int32","myField");

                //myField.Attributes = MemberAttributes.Private;

           MyClass.Members.Add(myField);

它的構(gòu)造函數(shù),前一個(gè)參數(shù)是類型,后一個(gè)參數(shù)是字段名。前一個(gè)參數(shù)有很多種寫(xiě)法,這在(三)里說(shuō)CodeParameterDeclarationExpression的時(shí)候提到過(guò)了(構(gòu)造函數(shù)有(Type,string)、(string,string)(CodeTypeReference,string)這三種寫(xiě)法),在CodeDOM里只要構(gòu)造函數(shù)有關(guān)于類型的一般都有上述的Type,string,CodeTypeReference三種寫(xiě)法。

Attribute對(duì)于字段來(lái)說(shuō)默認(rèn)是private。所以這里可以注釋掉。

一般地上面幾點(diǎn)就夠了,如果字段聲明的同時(shí)要初始化的,只要設(shè)一下InitExpression就是了,這跟變量聲明不太一樣的地方是,它沒(méi)有相應(yīng)的構(gòu)造函數(shù),只能先new出來(lái)后,再設(shè)置相應(yīng)的InitExpression屬性。下面四句

                CodeMemberField myArray = new CodeMemberField("System.Int32[]","myArray");

                myArray.Attributes = MemberAttributes.Private;

                myArray.InitExpression = new CodeArrayCreateExpression("System.Int32",10);

           MyClass.Members.Add(myArray);

產(chǎn)生private int[] myArray = new int[10];

 

數(shù)組比較的特別一點(diǎn),聲明的時(shí)候倒是容易,直接也在類型后加個(gè)“[]”就行了,就是初始化的時(shí)候麻煩一點(diǎn),要用到數(shù)組創(chuàng)建表達(dá)式CodeArrayCreateExpression。它的用法參照一下對(duì)應(yīng)的產(chǎn)生代碼就明白了,構(gòu)造函數(shù)都是大同小異的。

 

字段聲明完,接著要寫(xiě)構(gòu)造函數(shù)了。構(gòu)造函數(shù)就是一個(gè)比較特殊的類方法,CodeConstructor就是從CodeMemberMethod繼承下來(lái)聲明構(gòu)造函數(shù)用的。除了名字不太一樣,用法與CodeMemberMethodCodeEntryPointMethod差不多,這里就不詳述了。

 

下面是屬性的寫(xiě)法:

                CodeMemberProperty MyProperty = new CodeMemberProperty();

                MyProperty.Name = "MyProperty";

                MyProperty.Type = new CodeTypeReference("System.Int32");

                MyProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;

                MyProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"myField")));

                MyProperty.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"myField"),

                     new CodePropertySetValueReferenceExpression()));

           MyClass.Members.Add(MyProperty);

這么長(zhǎng)長(zhǎng)的一段出來(lái)

        public int MyProperty {

            get {

                return this.myField;

            }

            set {

                this.myField = value;

            }

        }

這個(gè)CodeMemberProperty從上往下看,就是依次設(shè)置屬性名、類型、可見(jiàn)性,以及getset方法的語(yǔ)句。這個(gè)GetStatements.Add()(或SetStatements.Add())里就隨你加了,簡(jiǎn)單的屬性設(shè)置就如上面一樣,復(fù)雜的話就不斷地依續(xù)再往里Add就是了。

下面簡(jiǎn)單的講一下GetSet里一些細(xì)節(jié)的東西。首先是return this.myField;這個(gè)是如何來(lái)的,上次講Fibonacci數(shù)列時(shí)沒(méi)講到,返回值語(yǔ)句就是由CodeMethodReturnStatement產(chǎn)生的,要返回什么構(gòu)造函數(shù)里就放什么,很簡(jiǎn)單。而this.myField就是類字段了,用CodeFieldReferenceExpression,不是上面的CodeMemberField,那個(gè)是聲明類字段用的,這里是要引用類字段(跟變量聲明與引用差不多)。同理CodePropertyReferenceExpression是就是用到類的屬性時(shí)用了。在屬性設(shè)置里“value”這個(gè)關(guān)鍵字會(huì)頻繁的出現(xiàn),在CodeDOM里對(duì)這個(gè)“value”也是有個(gè)專門(mén)的類的,就是CodePropertySetValueReferenceExpression了。比較特別的東西總是有個(gè)專門(mén)的類來(lái)表示,就象“this”就用CodeThisReferenceExpression來(lái)表示一樣。

 

在類的屬性里有個(gè)比較特殊的屬性就是索引器屬性,設(shè)置索引器屬性的寫(xiě)法與設(shè)置一般的屬性基本一樣,只是把屬性名改為“Item”就行了。如:

public int this[int index] {。。。。。略} 

這么一個(gè)索引器屬性由下述的語(yǔ)句產(chǎn)生:

                CodeMemberProperty Pindex = new CodeMemberProperty();

                Pindex.Comments.Add(new CodeCommentStatement("索引器屬性"));

                Pindex.Type = new CodeTypeReference("System.Int32");

                Pindex.Name = "Item";//屬性名設(shè)為Item時(shí),CodeDOM就當(dāng)作是索引器屬性處理

                Pindex.Attributes = MemberAttributes.Public | MemberAttributes.Final;

           Pindex.Parameters.Add(new CodeParameterDeclarationExpression("System.Int32","index"));

。。。。下略

 

類屬性的設(shè)置是夠麻煩的,但最麻煩的要數(shù)類事件了,如果只是聲明一下事件倒是簡(jiǎn)單得很,但講到事件就不得不講委托,這一下篇幅就長(zhǎng)了。這留下次講。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多