版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第4章面向對象編程進階4.1類的繼承與多態(tài)4.2操作符重載4.3類型轉換4.4結構與接口4.5集合與索引器4.6異常處理4.7委托與事件4.8預處理命令4.9組件與程序集4.10泛型4.1類的繼承與多態(tài)4.1.1繼承1.使用繼承繼承是指這樣一種能力:它可以使用現(xiàn)有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。使用繼承而產(chǎn)生的類被稱為派生類或者子類,而被繼承的類則稱為基類、超類或父類??陀^世界中的許多事物之間往往都是具有相同的特征,具有繼承的特點。圖4.1和圖4.2是兩個采用類的層次圖表示繼承的例子。
4.1.1繼承下面就來用編程實現(xiàn)圖4.2所示類的層次結構?!纠?.1】類的繼承。運行結果如圖4.3所示。4.1.1繼承2.base關鍵字例4.1程序中的square類也可以改寫為: //派生類Square,從Rectangular類中派生 publicclassSquare:Rectangular { publicSquare(stringColor,doubleSide):base(Color,Side,Side) {;} }關鍵字base的作用是調用Rectangular類的構造函數(shù)并將Square類的變量初始化。如果將Square類改寫成: //派生類Square,從Rectangular類中派生 publicclassSquare:Rectangular { publicSquare(stringColor,doubleSide) {;} }4.1.1繼承實際上這種情況調用的是父類的無參構造函數(shù),而不是有參構造函數(shù),等同于: //派生類Square,從Rectangular類中派生 publicclassSquare:Rectangular { publicSquare(stringColor,doubleSide):base() {;} }base關鍵字除了能調用基類對象構造函數(shù),還可以調用基類的方法。在下例中,Employee類的GetInfoEmployee方法使用了base關鍵字調用基類Person的GetInfoPerson方法?!纠?.2】base調用基類的方法。4.1.1繼承3.繼承中的構造函數(shù)與析構函數(shù)【例4.3】繼承中的構造函數(shù)與析構函數(shù)。運行結果如圖4.4所示。4.1.1繼承4.System.Object類C#所有類都派生于System.Object類。在定義類時如果沒有指定派生于哪一個類,系統(tǒng)就默認其派生于Object類。例4.2中Shape的定義就等同于:publicclassShape:System.Object{ …}System.Object類常見的公有方法有:(1)Equals:如果兩個對象具有相同值時,方法將返回true。(2)GetHashCode:方法返回對象的值的散列碼。(3)ToString:通過在派生類中重寫該方法,返回一個表示對象狀態(tài)的字符串。4.1.2多態(tài)1.虛方法的重載【例4.4】虛方法的重載。在A類定義了提供了非虛的F和虛方法G,派生類B則對方法F實現(xiàn)覆蓋,對虛方法G實現(xiàn)了虛方法的的重載?!癆a=b”實際上a仍舊是一個b對象。輸出結果如圖4.5所示:4.1.2多態(tài)在例4.1中計算圓形和矩形的面積分用了兩個不同的方法GetArea和AreaIs,也可以通過虛方法實現(xiàn)。將Shape中增加虛方法: publicvirtualdoubleGetArea() { return0.0; }在Circle類中對虛方法重載: publicoverridedoubleGetArea() { returnSystem.Math.PI*radius*radius; }在Rectangular類中對虛方法重載: publicoverridedoubleGetArea() { returnLength*Width; }4.1.2多態(tài)【例4.5】用虛方法的實現(xiàn)重載。運行的結果如圖4.6所示。4.1.2多態(tài)2.抽象類與抽象方法抽象類是一種特殊的基類,并不與具體的事物聯(lián)系。抽象類的定義使用關鍵字abstract。在圖4.2類的層次結構中,并沒有“圖形”這樣具體事物,所以可以將“圖形”定義為抽象類,派生了“圓形”和“四邊形”這樣一些可以產(chǎn)生具體實例化的普通類。需要注意的是,抽象類是不能被實例化,它只能作為其它類的基類。將Shape類定義為抽象類: publicabstractclassShape {… }4.1.2多態(tài)在抽象類中也可以使用關鍵字abstract定義抽象方法,要求所有的派生非抽象類都要重載實現(xiàn)抽象方法。引入抽象方法的原因在于抽象類本身是一種抽象的概念,有的方法并不要具體的實現(xiàn),而是留下來讓派生類來重載實現(xiàn)。Shape類中GetArea方法本身沒什么具體的意義,而只有到了派生類Circle類和Rectangular才可以計算具體的面積。抽象方法寫法:publicabstractdoubleGetArea();則派生類重載實現(xiàn)為: publicoverridedoubleGetArea() { … }【例4.6】抽象類和抽象方法的實現(xiàn)。4.1.2多態(tài)3.密封類和密封方法抽象類是作為基類,不能被實例化,由其它類繼承。相對應的還有一種不能被其它類繼承的類,叫密封類,使用sealed關鍵字定義。如果Rectangular類定義為密封類
:publicclassRectangular:Shape{…}這樣Rectangular類的派生類Square就不再保留,否則,就會出錯。4.1.2多態(tài)如果類的方法聲明包含sealed修飾符,稱該方法為密封方法。類的實例方法聲明包含sealed修飾符,則必須同時使用override修飾符。使用密封方法可以防止派生類進一步重寫該方法。如果將圓形Circle類的GetArea方法定義為密封類,必須先將Shape類GetArea方法定義為: publicvirtualdoubleGetArea() { … }然后在Circle類中實現(xiàn)密封方法: publicsealedoverridedoubleGetArea() { … }4.2操作符重載如果有一個復數(shù)Complex類對一元操作符“++”重載,可以寫成:publicstaticComplexoperator++(Complexa) { … }對二元操作符“+”可以寫成:publicstaticComplexoperator+(Complexa,Complexb) { … }4.2操作符重載一元操作符有一個參數(shù),二元操作符有二個參數(shù)。重載操作符開始必須以publicstatic修飾??梢灾剌d的操作符包括:一元操作符:+-!~++--truefalse二元操作符:+-*/%&|^<<>>==!=><>=<=下面的操作符要求同時重載,不能重載中間的單獨一個:一元操作符:true和false二元操作符:==和!=,>和<,>=和<=操作符重載給類的一些操作帶來了方便。兩個復數(shù)的實部相加運算寫成: publicstaticdoubleAdd(complexa,complexb) { returna.r+b.r }4.2操作符重載【例4.7】操作符重載的實現(xiàn)。運行結果如圖4.7所示。4.2操作符重載轉換過程不會丟失數(shù)據(jù)而出現(xiàn)異常,就采用隱式轉換。如果轉換過程有可能丟失數(shù)據(jù),就要采用顯式轉換。隱式類型轉換的寫法如: publicstaticimplicitoperatorSquare(doubles) { … }實現(xiàn)double向Square轉換功能。關鍵字explicit實現(xiàn)顯式類型轉換: publicstaticexplicitoperatordouble(Squares) { … }4.2操作符重載【例4.8】用戶定義的數(shù)據(jù)類型轉換。運行結果如圖4.8所示。4.3類型轉換4.3.1隱式類型轉換1.隱式數(shù)值轉換數(shù)值轉換是指在整數(shù)類型、實數(shù)類型和字符類型之間的轉換。sbyte類型向int類型轉換是一種隱式數(shù)值類型轉換,轉換一般不會失敗,也不會丟失數(shù)據(jù)。如:sbytea=100;intb=a;隱式數(shù)值類型轉換如表4.1所示。原始類型可轉換到的類型可能有信息丟失sbyteshort,int,long,float,double,decimal
byteshort,ushort,int,uint,long,ulong,float,double,decimal
shortint,long,float,double,decimal
ushortint,uint,long,ulong,float,double,decimal
intlong,float,double,decimalfloatuintlong,ulong,float,double,decimalfloatlongfloat,double,decimalfloat,doubleulongfloat,double,decimalfloat,doublecharushort,int,uint,long,ulong,float,double,decimal
floatdouble
4.3.1隱式類型轉換【例4.9】隱式數(shù)值轉換。namespaceEx4_9{classProgram{staticvoidMain(string[]args){chara='m';intb=a;Console.WriteLine("aequals:{0}",a);Console.WriteLine("bequals:{0}",b);Console.Read();}}}4.3.1隱式類型轉換運行結果如圖4.9所示:4.3.1隱式類型轉換如果這樣寫: intb=7; chara=b; Console.WriteLine("aequals:{0}",a); Console.WriteLine("bequals:{0}",b);編譯器將報錯,無法將類型“int”隱式轉換為“char”,如圖4.10所示。4.3.1隱式類型轉換2.隱式枚舉轉換【例4.10】隱式枚舉轉換。namespaceEx4_10{enumColor{Red,Green,Blue}classProgram{staticvoidMain(string[]args){Colora=Color.Red;Console.WriteLine("aequals:{0}",a);a=0;Console.WriteLine("aequals:{0}",a);Console.Read();}}}4.3.1隱式類型轉換運行結果如圖4.11所示。如果寫a=1或其他數(shù)值,編譯器提示無法將類型“int”隱式轉換為“Color”,如圖4.12所示。4.3.1隱式類型轉換3.隱式引用轉換類型s向類型t隱式引用轉換的條件是:s是從t派生來的,且s和t可以是接口或類。兩個數(shù)組的之間的隱式轉換的條件是:兩個數(shù)組的維數(shù)相同,元素都是引用類型,且存在數(shù)組元素的隱式引用轉換。例如: classEmployee //隱含繼承自System.Object {… } classApp {Employeee;objecto=e;… }4.3.2顯式類型轉換1.顯式數(shù)值轉換int類型向byte類型轉換就是一種顯式數(shù)值類型轉換。例如:intb=100;sbytea=(byte)b;sbyte取值范圍是0~255,當intb顯式轉換為sbyte時不會丟失信息。intb=1000;sbytea=(byte)b;則會出信息丟失,這是顯式數(shù)值轉換過程要注意的。4.3.2顯式類型轉換顯式數(shù)值類型可轉換的類型如表4.2。原始類型可轉換到的類型sbytebyte,ushort,uint,ulong,charbytesbyte,charshortsbyte,byte,ushort,uint,ulong,charushortsbyte,byte,short,charintsbyte,byte,short,ushort,uint,ulong,charuintsbyte,byte,short,ushort,int,charlongsbyte,byte,short,ushort,int,uint,ulong,charulongsbyte,byte,short,ushort,int,uint,long,charcharsbyte,byte,shortfloatsbyte,byte,short,ushort,int,uint,long,ulong,char,decimaldoublesbyte,byte,short,ushort,int,uint,long,ulong,char,float,decimaldecimalsbyte,byte,short,ushort,int,uint,long,ulong,char,float,double4.3.2顯式類型轉換2.顯式枚舉轉換顯式枚舉轉換包括幾種情況:從sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,decimal類型到任何枚舉類型;從任何枚舉類型到sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,decimal;從任何枚舉類型到任何其它枚舉類型。顯式枚舉轉換其本質是枚舉類型的元素類型與要轉換的類型之間的顯式轉換?!纠?.11】顯式枚舉轉換。運行結果如圖4.13:4.3.2顯式類型轉換3.顯式引用轉換類型s向類型t顯式引用轉換的條件是t是從s派生來的,且s和t可以是接口或類。兩個數(shù)組的之間的顯式轉換的條件是兩個數(shù)組的維數(shù)相同,元素都是引用類型,不能有任何一方是值類型數(shù)組,且存在數(shù)組元素的顯式或隱式轉換。例如: classEmployee //隱含繼承自System.Object { … } classApp { objecto Employeee=(Employee)o; … }4.3.3使用CONVERT轉換System.Convert類中有一套的靜態(tài)方法實現(xiàn)類型的轉換,即使要轉換的類型之間沒有什么聯(lián)系也可以很方便的實現(xiàn)類型的轉換。包括的方法列在表4.3中。方法實現(xiàn)的轉換Convert.ToBoolean()轉換為boolConvert.ToByte()轉換為byteConvert.ToChar()轉換為charConvert.ToString()轉換為stringConvert.ToDecimal()轉換為decimalConvert.ToDouble()轉換為doubleConvert.ToInt16()轉換為shortConvert.ToInt32()轉換為intConvert.ToInt64()轉換為longConvert.ToSByte()轉換為sbyteConvert.ToSingle()轉換為floatConvert.ToUInt16()轉換為ushortConvert.ToUInt32()轉換為uintConvert.ToUInt64()轉換為ulong4.3.3使用CONVERT轉換有關異常處理知識見4.6節(jié)。例如,從Char轉換為Boolean、Single、Double、Decimal,以及從這些類型轉換為Char都會引發(fā)異常。 stringstr=“32767”; System.Convert.ToInt16(str);可以正常的類型轉換。但是, stringstr=“32768”; System.Convert.ToInt16(str);或: stringstr=“”; System.Convert.ToInt16(str);4.3.3使用CONVERT轉換【例4.12】System.Convert實現(xiàn)類型轉換。運行結果如圖4.14所示。4.4結構與接口4.4.1結構C#中的結構除了包含有數(shù)據(jù)成員,還有構造函數(shù)、方法、屬性、事件、索引等成員,結構也可以實現(xiàn)多個接口。結構與類很類似,但也有很多的區(qū)別。首先結構是值類型,而類是引用類型?!纠?.13】值類型的結構。運行結果如圖4.15所示。4.4.1結構結構實例化時也可以不用new。例如,Class1也可以寫成:classClass1{ staticvoidMain() { MyStructs1; s1.x=1; s1.y=2; MyStructs2=s1; s1.x=2; s1.Sum(); s2.Sum(); }}如果在Main()加入:MyStructs3=newMyStruct();s3.Sum();4.4.1結構結構與類的區(qū)別如表4.4所示。結構類值類型引用類型可以不使用new實例化必須使用new初始化沒有默認的構造函數(shù),但可以添加構造函數(shù)有默認的構造函數(shù)沒有析構函數(shù)有析構函數(shù)沒有abstract,protected和sealed修飾符可以使用abstract,protected和sealed修飾符4.4.2接口1.接口介紹接口是用來定義一種程序的協(xié)定,它好比一種模版,定義了實現(xiàn)接口的對象必須實現(xiàn)的方法,其目的就是讓這些方法可以作為接口實例被引用。接口的定義如: publicinterfaceIPartA { voidSetDataA(stringdataA); }4.4.2接口【例4.14】接口演示。運行結果如圖4.16所示:4.4.2接口接口允許多重繼承: interfaceID:IA,IB,IC { … } 類可以同時有一個基類和零個以上的接口,并要將基類寫在前面: classClassB:ClassA,IA,IB { … }4.4.2接口2.接口的實現(xiàn)指出接口成員所在的接口,則稱為顯式接口成員。上面程序接口實現(xiàn)可改寫成://沒有定義為publicvoidIPartA.SetDataA(stringdataA) { DataA=dataA; Console.WriteLine("{0}",DataA); }//沒有定義為publicvoidIPartB.SetDataB(stringdataB) { DataB=dataB; Console.WriteLine("{0}",DataB); }4.4.2接口顯式接口成員只能通過接口來調用。 classtest{ staticvoidMain() { SharedClassa=newSharedClass(); IPartBpartb=a; partb.SetDataA("interfaceIPartA"); partb.SetDataB("interfaceIPartB"); }}4.4.2接口【例4.15】顯式接口調用。運行結果如圖4.17所示。4.5集合與索引器4.5.1集合1.自定義集合自定義集合是指實現(xiàn)System.Collections提供的集合接口的集合。下面以IEnumerable集合接口為例自定義集合。IEnumerable接口定義:publicinterfaceIEnumerable{IenumeratorGetEnumerator();}實現(xiàn)IEnumerable的同時也要實現(xiàn)IEnumerator接口。IEnumerator接口為:publicinterfaceIEnumerator{ objectCurrent {get(); } boolMoveNext(); voidReset();}4.5.1集合【例4.16】IEnumerable自定義集合。運行結果如圖4.18所示。4.5.1集合2.使用集合類另一種使用集合的方法是使用系統(tǒng)已經(jīng)定義的集合類。下面就以Stack類為例介紹。Stack類表示對象的后進先出集合。Stack類常用的方法有:Clear:從Stack中移除所有對象Pop:移除并返回位于Stack頂部的對象Push:將對象插入Stack的頂部Peek:返回位于Stack頂部的對象但不將其移除4.5.1集合【例4.17】Stack類的用法示例。運行結果如圖4.19所示。4.5.2索引器【例4.18】索引器示例。運行結果如圖4.20所示。4.5.2索引器【例4.19】包含計算和控制代碼的索引器。運行結果如圖4.21所示。4.6異常處理4.6.1異常與異常類1.異常Win32API程序出現(xiàn)錯誤時,沒有使用異常處理機制作處理,大多數(shù)的Win32API都是通過返回bool值,用false來表示函數(shù)調用出了問題。COM用HRESULT來描述程序的運行情況。當HRESULT的高位為1,則表示一個假設被違反,HRESULT的其它位則可以幫助判斷問題的原因。請看下的代碼: boolRemoveFromAccount(stringAccountId,decimalAmount){ boolExists=VerifyAccountId(AccountId); if(Exists) { boolCanWithdraw=CheckAvailability(AccountId,Amount); if(CanWithdraw) { returnWithdraw(AccountId,Amount); } } returnfalse;}4.6.1異常與異常類2.異常類System.Exception類是異常類的基類,一般不要直接使用System.Exception,它沒有反映具體的異常信息,而是一般用它的派生類。 System.Exception提供了一些了解異常信息的屬性,如表4.5。屬性訪問權限類型描述HelpLink只讀String獲取或設置指向此異常所關聯(lián)幫助文件的鏈接。InnerException只讀Exception獲取導致當前異常的Exception實例。Message只讀String獲取描述當前異常的消息。Source讀/寫String獲取或設置導致錯誤的應用程序或對象的名稱。StackTrace只讀String獲取當前異常發(fā)生所經(jīng)歷的方法的名稱和簽名。TargetSite只讀MethodBase獲取引發(fā)當前異常的方法。4.6.1異常與異常類經(jīng)常使用的C#異常類見表4.6。異常類描述System.ArithmeticException在算術運算期間發(fā)生的異常(如System.DivideByZeroException和System.OverflowException)的基類。System.ArrayTypeMismatchException當存儲一個數(shù)組時,如果由于被存儲的元素的實際類型與數(shù)組的實際類型不兼容而導致存儲失敗,就會引發(fā)此異常。System.DivideByZeroException在試圖用零除整數(shù)值時引發(fā)。System.IndexOutOfRangeException在試圖使用小于零或超出數(shù)組界限的下標索引數(shù)組時引發(fā)。System.InvalidCastException當從基類型或接口到派生類型的顯式轉換在運行時失敗時,就會引發(fā)此異常。System.NullReferenceException在需要使用引用對象的場合,如果使用null引用,就會引發(fā)此異常。System.OutOfMemoryException在分配內存(通過new)的嘗試失敗時引發(fā)。System.OverflowException在checked上下文中的算術運算溢出時引發(fā)。System.StackOverflowException當執(zhí)行堆棧由于保存了太多掛起的方法調用而耗盡時,就會引發(fā)此異常;這通常表明存在非常深或無限的遞歸。System.TypeInitializationException在靜態(tài)構造函數(shù)引發(fā)異常并且沒有可以捕捉到它的catch子句時引發(fā)。4.6.2異常處理1.try語句將有可能發(fā)生異常的代碼作為try語句塊,處理try語句中出現(xiàn)的異常代碼放到catch語句塊。finally語句則是不管try語句中有沒有異常發(fā)生最后都要執(zhí)行其中的程序塊。【例4.20】try-catch-finally語句示例。運行結果如圖4.22所示。4.6.2異常處理catch塊中包含的是出現(xiàn)異常時要執(zhí)行的代碼。一個try后面可以有零個以上的catch塊。如果try塊中沒有異常,則catch塊中代碼不會被執(zhí)行。catch后面括號放入希望捕獲的異常,如例4.20中DivideByZeroException異常。當兩個catch語句的異常類有派生關系的時候,要將包括派生的異常類catch語句放到前面,包括基類的catch語句放置到后面。finally塊包含了一定要執(zhí)行的代碼,通常是一些資源釋放,關閉文件等代碼。【例4.21】多catch語句示例。運行結果如圖4.23所示。4.6.2異常處理2.throw異常的發(fā)生有兩種可能:代碼執(zhí)行過程中滿足了異常的條件而使程序無法正常運行下去;通過throw語句無條件拋出異常。第一種情況上面已經(jīng)介紹過了。第二種情況則與第一種情況完全相反,通過throw語句主動在程序中拋出異常,拋出的異常要用catch語句捕獲,否則程序運行將中斷。throw語句用法:throwexpressionthrow語句拋出的異常表達式expression必須表示一個System.Exception類型或它的派生類。4.6.2異常處理【例4.22】throw語句拋出異常。運行結果如圖4.24所示。4.6.2異常處理throw語句重新拋出一個新的異常ArithmeticException,然后出由Main()中catch捕獲?!纠?.23】throw語句異常再次拋出。運行結果如圖4.25所示。throw語句將Div()的DivideByZeroException再次拋出,由Main()中catch語句捕獲它?!纠?.24】異常處理綜合舉例。4.7委托與事件4.7.1委托1.委托C#的委托相當于在C/C++中的函數(shù)指針。函數(shù)指針用指針獲取一個函數(shù)的入口地址,實現(xiàn)對函數(shù)的操作。委托與C/C++中的函數(shù)指針不同在于委托是面向對象的,是引用類型,因此對委托的使用要先定義后實例化,最后才調用。定義委托使用關鍵字delegate,定義一個委托:delegateintSomeDelegate(intnID,stringsName);再實例化:SomeDelegated1=newSomeDelegate(wr.InstanceMethod);最后調用:d1(5,"aaa");通過委托SomeDelegate實現(xiàn)對方法InstanceMethod的調用,調用還必須有一個前提條件是:方法InstanceMethod有參數(shù)和定義SomeDelegate的參數(shù)一致,并且返回值為int。方法InstanceMethod定義:publicintInstanceMethod(intnID,stringsName)4.7.1委托【例4.25】委托示例。運行結果如圖4.26所示。4.7.1委托2.多播相對于上面的一次委托只調用一個方法,一次委托也可以調用多個方法,稱為多播。通過+和-運算符實現(xiàn)多播的增加或減少?!纠?.26】多播示例。運行結果如圖4.27所示。4.7.1委托委托是從System.Delegate類派生而來,多播則派生于System.Delegate的派生類System.MulticastDelegate,對于下面代碼:SomeDelegated3=d1+d2;也可以用Delegate.Combine方法寫成:SomeDelegated3=(SomeDelegate)Delegate.Combine(d1,d2);也可以使用MulticastDelegate.Combine的方法寫成:SomeDelegated3=(SomeDelegate)MulticastDelegate.Combine(d1,d2);4.7.2事件C#事件是按“發(fā)布-預訂”的方式工作。先在一個類中公布事件,然后就可以在任意數(shù)量的類中對事件預訂。事件的工作過程可以用圖4.28表示:4.7.2事件C#事件機制是基于委托實現(xiàn)的,因此要首先定義一個委托EventHandler:publicdelegatevoidEventHandler(objectfrom,myEventArgse)System.EventArgs是包含事件數(shù)據(jù)的類的基類,在代碼中可直接使用EventArgs類。myEventArgs類派生于EventArgs類,實現(xiàn)自定義事件數(shù)據(jù)的功能。這里from表示發(fā)生事件的對象。定義事件格式為:event事件的委托名事件名如事件TextOut定義:publiceventEventHandlerTextOut;事件的激活一般寫成:if(TextOut!=null) TextOut(this,newEventArgs());4.7.2事件檢查TextOut事件有沒有被訂閱,如不為null,則表示有用戶訂閱。訂閱事件的是TestApp類,首先實例化EventSource,然后訂閱事件:evsrc.TextOut+=newEventSource.EventHandler(CatchEvent);也可以取消訂閱:evsrc.TextOut-=newEventSource.EventHandler(CatchEvent);方法evsrc.TriggerEvent()激活事件,如果已經(jīng)訂閱了事件,則調用處理代碼,否則什么也沒有不執(zhí)行。4.7.2事件【例4.27】事件示例。運行結果如圖4.29所示。4.8預處理命令4.8.1#define、#undef指令#define和#undef指令是用于定義符號和取消符號定義的預處理指令。#defineDEBUG#undefDEBUG這里定義和取消的符號是DEBUB。如果定義的符號已經(jīng)存在,#define則不起作用,同樣道理,如果符號不存在,#undef也就沒有任何作用。#define和#undef指令必須放于源程序的代碼之前。usingSystem;#defineDEBUG4.8.2#IF、#ELIF、#ELSE、#ENDIF指令#if、#elif、#else、#endif指令被用作條件編譯,它們類似于if/else結構。#if和#elif后的標識符表達式可以使用運算符與(&&)、或(||)、非(!)。它們在程序中結構如下所示:一條#if語句(必須有)零或多條#elif語句零或一條#else語句一條#endif語句(必須有)【例4.28】預處理示例。運行結果如圖4.30所示。4.8.2#IF、#ELIF、#ELSE、#ENDIF指令當執(zhí)行到#if語句,首先檢查DEBUG是否已經(jīng)定義,如果符號已經(jīng)定義,就編譯#if塊中的代碼,否則編譯#else塊中的代碼。#elif指令相當于“elseif”?!纠?.29】#elif指令。運行結果如圖4.31所示。4.8.3#WARNING、#ERROR指令#warning、#error指令用于產(chǎn)生警告或錯誤。當編譯器遇到#warning指令時,會顯示#waring后面的文本,編譯還會繼續(xù)進行。當遇到#error指令時,會顯示后面的文本,并終止編譯退出。這兩條指令可以用于檢查#define是否定義了什么不正確的符號。 #defineDEBUG #defineRELEASE #ifDEBUG #error你定義了DEBUG #endif #ifDEBUG&&RELEASE #warning你定義了DEBUG和RELEASE #endif4.8.4#REGION、#ENDREGION指令#region、#endregion指令用于標識代碼塊。#regionOutVarmethod publicstaticvoidOutVar() { intvar=5; Console.WriteLine("varequals:{0}",var); } #endregion4.8.5#LINE指令#line指令用于改變編譯器在警告或錯誤信息中顯示的文件名和行號信息。當發(fā)生警告或錯誤時,不再顯示源程序中的實際位置,而是#line指定的行數(shù)。#line100 //指定行號為100#line200“test.cs” //test.cs替換原來的文件名作為編譯輸出文件名4.9組件與程序集4.9.1組件從軟件模型的角度考慮,人們將龐大的應用程序分割成為多個模塊,每個模塊完成獨立的功能,模塊之間協(xié)同工作,這樣的模塊我們稱為組件。這些組件可以進行單獨開發(fā),單獨編譯,單獨測試,把所有的組件組合在一起就得到了完整的系統(tǒng)。組件有不同方式的定義。范圍最廣的定義是組件包括二進制代碼,也就是說它是可執(zhí)行的代碼,而不是未編譯的源代碼。DLL文件從這個意義上來說就是一種組件。較窄范圍的概念是組件提供一種手段,將內容告訴其他程序,程序集具有這樣的功能。最嚴格的定義要求組件提供已知的接口,釋放不再使用的系統(tǒng)資源并提供與設計工具的集成功能。在.NET框架中,組件是指實現(xiàn)System.ComponentModel.IComponent接口的一個類,或從實現(xiàn)IComponent的類中直接或間接派生的類。.NET框架組件滿足這一要求。4.9.2程序集在安全問題上,.NET框架包含了代碼訪問安全(codeaccesssecurity)的新型安全模型。Windows安全是基于用戶的身份,代碼訪問安全則是基于程序集的標識,我們可以自己決定程序集的安全許可,如信任微軟發(fā)布的程序集,或者不信任何從網(wǎng)上下載的程序集,.NET框架為計算機中安裝內容和運行的程序有了更多的控制權。包含有一個文件的程序集的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版電子元件采購合同數(shù)量取消及供應鏈調整補充協(xié)議3篇
- 2024建造師勞動合同
- 2025年度民族特色餐廳租賃及文化傳承合作協(xié)議3篇
- 二零二五年房地產(chǎn)糾紛調解估價委托合同模板3篇
- 2024年項目聯(lián)合開發(fā)協(xié)議3篇
- 二零二五年度高品質建筑材料租賃與運輸管理合同3篇
- 二零二五版商用空調租賃與能源消耗優(yōu)化合同3篇
- 威海職業(yè)學院《突發(fā)公衛(wèi)事件應急處理》2023-2024學年第一學期期末試卷
- 天津城市職業(yè)學院《災害防御與避險應急》2023-2024學年第一學期期末試卷
- 太原城市職業(yè)技術學院《普通生物學》2023-2024學年第一學期期末試卷
- (隱蔽)工程現(xiàn)場收方計量記錄表
- DB22T 5005-2018 注塑夾芯復合保溫砌塊自保溫墻體工程技術標準
- 醫(yī)院手術室醫(yī)院感染管理質量督查評分表
- 心內電生理導管及器械
- 稱量與天平培訓試題及答案
- 超全的超濾與納濾概述、基本理論和應用
- 2020年醫(yī)師定期考核試題與答案(公衛(wèi)專業(yè))
- 2022年中國育齡女性生殖健康研究報告
- 各種靜脈置管固定方法
- 消防報審驗收程序及表格
- 教育金規(guī)劃ppt課件
評論
0/150
提交評論