




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第4章面向?qū)ο缶幊踢M(jìn)階4.1類的繼承與多態(tài)4.2操作符重載4.3類型轉(zhuǎn)換4.4結(jié)構(gòu)與接口4.5集合與索引器4.6異常處理4.7委托與事件4.8預(yù)處理命令4.9組件與程序集4.10泛型4.1類的繼承與多態(tài)4.1.1繼承1.使用繼承繼承是指這樣一種能力:它可以使用現(xiàn)有類的所有功能,并在無(wú)需重新編寫原來(lái)的類的情況下對(duì)這些功能進(jìn)行擴(kuò)展。使用繼承而產(chǎn)生的類被稱為派生類或者子類,而被繼承的類則稱為基類、超類或父類??陀^世界中的許多事物之間往往都是具有相同的特征,具有繼承的特點(diǎn)。圖4.1和圖4.2是兩個(gè)采用類的層次圖表示繼承的例子。
4.1.1繼承下面就來(lái)用編程實(shí)現(xiàn)圖4.2所示類的層次結(jié)構(gòu)?!纠?.1】類的繼承。運(yùn)行結(jié)果如圖4.3所示。4.1.1繼承2.base關(guān)鍵字例4.1程序中的square類也可以改寫為: //派生類Square,從Rectangular類中派生 publicclassSquare:Rectangular { publicSquare(stringColor,doubleSide):base(Color,Side,Side) {;} }關(guān)鍵字base的作用是調(diào)用Rectangular類的構(gòu)造函數(shù)并將Square類的變量初始化。如果將Square類改寫成: //派生類Square,從Rectangular類中派生 publicclassSquare:Rectangular { publicSquare(stringColor,doubleSide) {;} }4.1.1繼承實(shí)際上這種情況調(diào)用的是父類的無(wú)參構(gòu)造函數(shù),而不是有參構(gòu)造函數(shù),等同于: //派生類Square,從Rectangular類中派生 publicclassSquare:Rectangular { publicSquare(stringColor,doubleSide):base() {;} }base關(guān)鍵字除了能調(diào)用基類對(duì)象構(gòu)造函數(shù),還可以調(diào)用基類的方法。在下例中,Employee類的GetInfoEmployee方法使用了base關(guān)鍵字調(diào)用基類Person的GetInfoPerson方法?!纠?.2】base調(diào)用基類的方法。4.1.1繼承3.繼承中的構(gòu)造函數(shù)與析構(gòu)函數(shù)【例4.3】繼承中的構(gòu)造函數(shù)與析構(gòu)函數(shù)。運(yùn)行結(jié)果如圖4.4所示。4.1.1繼承4.System.Object類C#所有類都派生于System.Object類。在定義類時(shí)如果沒有指定派生于哪一個(gè)類,系統(tǒng)就默認(rèn)其派生于Object類。例4.2中Shape的定義就等同于:publicclassShape:System.Object{ …}System.Object類常見的公有方法有:(1)Equals:如果兩個(gè)對(duì)象具有相同值時(shí),方法將返回true。(2)GetHashCode:方法返回對(duì)象的值的散列碼。(3)ToString:通過在派生類中重寫該方法,返回一個(gè)表示對(duì)象狀態(tài)的字符串。4.1.2多態(tài)1.虛方法的重載【例4.4】虛方法的重載。在A類定義了提供了非虛的F和虛方法G,派生類B則對(duì)方法F實(shí)現(xiàn)覆蓋,對(duì)虛方法G實(shí)現(xiàn)了虛方法的的重載?!癆a=b”實(shí)際上a仍舊是一個(gè)b對(duì)象。輸出結(jié)果如圖4.5所示:4.1.2多態(tài)在例4.1中計(jì)算圓形和矩形的面積分用了兩個(gè)不同的方法GetArea和AreaIs,也可以通過虛方法實(shí)現(xiàn)。將Shape中增加虛方法: publicvirtualdoubleGetArea() { return0.0; }在Circle類中對(duì)虛方法重載: publicoverridedoubleGetArea() { returnSystem.Math.PI*radius*radius; }在Rectangular類中對(duì)虛方法重載: publicoverridedoubleGetArea() { returnLength*Width; }4.1.2多態(tài)【例4.5】用虛方法的實(shí)現(xiàn)重載。運(yùn)行的結(jié)果如圖4.6所示。4.1.2多態(tài)2.抽象類與抽象方法抽象類是一種特殊的基類,并不與具體的事物聯(lián)系。抽象類的定義使用關(guān)鍵字abstract。在圖4.2類的層次結(jié)構(gòu)中,并沒有“圖形”這樣具體事物,所以可以將“圖形”定義為抽象類,派生了“圓形”和“四邊形”這樣一些可以產(chǎn)生具體實(shí)例化的普通類。需要注意的是,抽象類是不能被實(shí)例化,它只能作為其它類的基類。將Shape類定義為抽象類: publicabstractclassShape {… }4.1.2多態(tài)在抽象類中也可以使用關(guān)鍵字abstract定義抽象方法,要求所有的派生非抽象類都要重載實(shí)現(xiàn)抽象方法。引入抽象方法的原因在于抽象類本身是一種抽象的概念,有的方法并不要具體的實(shí)現(xiàn),而是留下來(lái)讓派生類來(lái)重載實(shí)現(xiàn)。Shape類中GetArea方法本身沒什么具體的意義,而只有到了派生類Circle類和Rectangular才可以計(jì)算具體的面積。抽象方法寫法:publicabstractdoubleGetArea();則派生類重載實(shí)現(xiàn)為: publicoverridedoubleGetArea() { … }【例4.6】抽象類和抽象方法的實(shí)現(xiàn)。4.1.2多態(tài)3.密封類和密封方法抽象類是作為基類,不能被實(shí)例化,由其它類繼承。相對(duì)應(yīng)的還有一種不能被其它類繼承的類,叫密封類,使用sealed關(guān)鍵字定義。如果Rectangular類定義為密封類
:publicclassRectangular:Shape{…}這樣Rectangular類的派生類Square就不再保留,否則,就會(huì)出錯(cuò)。4.1.2多態(tài)如果類的方法聲明包含sealed修飾符,稱該方法為密封方法。類的實(shí)例方法聲明包含sealed修飾符,則必須同時(shí)使用override修飾符。使用密封方法可以防止派生類進(jìn)一步重寫該方法。如果將圓形Circle類的GetArea方法定義為密封類,必須先將Shape類GetArea方法定義為: publicvirtualdoubleGetArea() { … }然后在Circle類中實(shí)現(xiàn)密封方法: publicsealedoverridedoubleGetArea() { … }4.2操作符重載如果有一個(gè)復(fù)數(shù)Complex類對(duì)一元操作符“++”重載,可以寫成:publicstaticComplexoperator++(Complexa) { … }對(duì)二元操作符“+”可以寫成:publicstaticComplexoperator+(Complexa,Complexb) { … }4.2操作符重載一元操作符有一個(gè)參數(shù),二元操作符有二個(gè)參數(shù)。重載操作符開始必須以publicstatic修飾??梢灾剌d的操作符包括:一元操作符:+-!~++--truefalse二元操作符:+-*/%&|^<<>>==!=><>=<=下面的操作符要求同時(shí)重載,不能重載中間的單獨(dú)一個(gè):一元操作符:true和false二元操作符:==和!=,>和<,>=和<=操作符重載給類的一些操作帶來(lái)了方便。兩個(gè)復(fù)數(shù)的實(shí)部相加運(yùn)算寫成: publicstaticdoubleAdd(complexa,complexb) { returna.r+b.r }4.2操作符重載【例4.7】操作符重載的實(shí)現(xiàn)。運(yùn)行結(jié)果如圖4.7所示。4.2操作符重載轉(zhuǎn)換過程不會(huì)丟失數(shù)據(jù)而出現(xiàn)異常,就采用隱式轉(zhuǎn)換。如果轉(zhuǎn)換過程有可能丟失數(shù)據(jù),就要采用顯式轉(zhuǎn)換。隱式類型轉(zhuǎn)換的寫法如: publicstaticimplicitoperatorSquare(doubles) { … }實(shí)現(xiàn)double向Square轉(zhuǎn)換功能。關(guān)鍵字explicit實(shí)現(xiàn)顯式類型轉(zhuǎn)換: publicstaticexplicitoperatordouble(Squares) { … }4.2操作符重載【例4.8】用戶定義的數(shù)據(jù)類型轉(zhuǎn)換。運(yùn)行結(jié)果如圖4.8所示。4.3類型轉(zhuǎn)換4.3.1隱式類型轉(zhuǎn)換1.隱式數(shù)值轉(zhuǎn)換數(shù)值轉(zhuǎn)換是指在整數(shù)類型、實(shí)數(shù)類型和字符類型之間的轉(zhuǎn)換。sbyte類型向int類型轉(zhuǎn)換是一種隱式數(shù)值類型轉(zhuǎn)換,轉(zhuǎn)換一般不會(huì)失敗,也不會(huì)丟失數(shù)據(jù)。如:sbytea=100;intb=a;隱式數(shù)值類型轉(zhuǎn)換如表4.1所示。原始類型可轉(zhuǎn)換到的類型可能有信息丟失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隱式類型轉(zhuǎn)換【例4.9】隱式數(shù)值轉(zhuǎn)換。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隱式類型轉(zhuǎn)換運(yùn)行結(jié)果如圖4.9所示:4.3.1隱式類型轉(zhuǎn)換如果這樣寫: intb=7; chara=b; Console.WriteLine("aequals:{0}",a); Console.WriteLine("bequals:{0}",b);編譯器將報(bào)錯(cuò),無(wú)法將類型“int”隱式轉(zhuǎn)換為“char”,如圖4.10所示。4.3.1隱式類型轉(zhuǎn)換2.隱式枚舉轉(zhuǎn)換【例4.10】隱式枚舉轉(zhuǎn)換。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隱式類型轉(zhuǎn)換運(yùn)行結(jié)果如圖4.11所示。如果寫a=1或其他數(shù)值,編譯器提示無(wú)法將類型“int”隱式轉(zhuǎn)換為“Color”,如圖4.12所示。4.3.1隱式類型轉(zhuǎn)換3.隱式引用轉(zhuǎn)換類型s向類型t隱式引用轉(zhuǎn)換的條件是:s是從t派生來(lái)的,且s和t可以是接口或類。兩個(gè)數(shù)組的之間的隱式轉(zhuǎn)換的條件是:兩個(gè)數(shù)組的維數(shù)相同,元素都是引用類型,且存在數(shù)組元素的隱式引用轉(zhuǎn)換。例如: classEmployee //隱含繼承自System.Object {… } classApp {Employeee;objecto=e;… }4.3.2顯式類型轉(zhuǎn)換1.顯式數(shù)值轉(zhuǎn)換int類型向byte類型轉(zhuǎn)換就是一種顯式數(shù)值類型轉(zhuǎn)換。例如:intb=100;sbytea=(byte)b;sbyte取值范圍是0~255,當(dāng)intb顯式轉(zhuǎn)換為sbyte時(shí)不會(huì)丟失信息。intb=1000;sbytea=(byte)b;則會(huì)出信息丟失,這是顯式數(shù)值轉(zhuǎn)換過程要注意的。4.3.2顯式類型轉(zhuǎn)換顯式數(shù)值類型可轉(zhuǎn)換的類型如表4.2。原始類型可轉(zhuǎn)換到的類型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顯式類型轉(zhuǎn)換2.顯式枚舉轉(zhuǎn)換顯式枚舉轉(zhuǎn)換包括幾種情況:從sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,decimal類型到任何枚舉類型;從任何枚舉類型到sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,decimal;從任何枚舉類型到任何其它枚舉類型。顯式枚舉轉(zhuǎn)換其本質(zhì)是枚舉類型的元素類型與要轉(zhuǎn)換的類型之間的顯式轉(zhuǎn)換?!纠?.11】顯式枚舉轉(zhuǎn)換。運(yùn)行結(jié)果如圖4.13:4.3.2顯式類型轉(zhuǎn)換3.顯式引用轉(zhuǎn)換類型s向類型t顯式引用轉(zhuǎn)換的條件是t是從s派生來(lái)的,且s和t可以是接口或類。兩個(gè)數(shù)組的之間的顯式轉(zhuǎn)換的條件是兩個(gè)數(shù)組的維數(shù)相同,元素都是引用類型,不能有任何一方是值類型數(shù)組,且存在數(shù)組元素的顯式或隱式轉(zhuǎn)換。例如: classEmployee //隱含繼承自System.Object { … } classApp { objecto Employeee=(Employee)o; … }4.3.3使用CONVERT轉(zhuǎn)換System.Convert類中有一套的靜態(tài)方法實(shí)現(xiàn)類型的轉(zhuǎn)換,即使要轉(zhuǎn)換的類型之間沒有什么聯(lián)系也可以很方便的實(shí)現(xiàn)類型的轉(zhuǎn)換。包括的方法列在表4.3中。方法實(shí)現(xiàn)的轉(zhuǎn)換Convert.ToBoolean()轉(zhuǎn)換為boolConvert.ToByte()轉(zhuǎn)換為byteConvert.ToChar()轉(zhuǎn)換為charConvert.ToString()轉(zhuǎn)換為stringConvert.ToDecimal()轉(zhuǎn)換為decimalConvert.ToDouble()轉(zhuǎn)換為doubleConvert.ToInt16()轉(zhuǎn)換為shortConvert.ToInt32()轉(zhuǎn)換為intConvert.ToInt64()轉(zhuǎn)換為longConvert.ToSByte()轉(zhuǎn)換為sbyteConvert.ToSingle()轉(zhuǎn)換為floatConvert.ToUInt16()轉(zhuǎn)換為ushortConvert.ToUInt32()轉(zhuǎn)換為uintConvert.ToUInt64()轉(zhuǎn)換為ulong4.3.3使用CONVERT轉(zhuǎn)換有關(guān)異常處理知識(shí)見4.6節(jié)。例如,從Char轉(zhuǎn)換為Boolean、Single、Double、Decimal,以及從這些類型轉(zhuǎn)換為Char都會(huì)引發(fā)異常。 stringstr=“32767”; System.Convert.ToInt16(str);可以正常的類型轉(zhuǎn)換。但是, stringstr=“32768”; System.Convert.ToInt16(str);或: stringstr=“”; System.Convert.ToInt16(str);4.3.3使用CONVERT轉(zhuǎn)換【例4.12】System.Convert實(shí)現(xiàn)類型轉(zhuǎn)換。運(yùn)行結(jié)果如圖4.14所示。4.4結(jié)構(gòu)與接口4.4.1結(jié)構(gòu)C#中的結(jié)構(gòu)除了包含有數(shù)據(jù)成員,還有構(gòu)造函數(shù)、方法、屬性、事件、索引等成員,結(jié)構(gòu)也可以實(shí)現(xiàn)多個(gè)接口。結(jié)構(gòu)與類很類似,但也有很多的區(qū)別。首先結(jié)構(gòu)是值類型,而類是引用類型?!纠?.13】值類型的結(jié)構(gòu)。運(yùn)行結(jié)果如圖4.15所示。4.4.1結(jié)構(gòu)結(jié)構(gòu)實(shí)例化時(shí)也可以不用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結(jié)構(gòu)結(jié)構(gòu)與類的區(qū)別如表4.4所示。結(jié)構(gòu)類值類型引用類型可以不使用new實(shí)例化必須使用new初始化沒有默認(rèn)的構(gòu)造函數(shù),但可以添加構(gòu)造函數(shù)有默認(rèn)的構(gòu)造函數(shù)沒有析構(gòu)函數(shù)有析構(gòu)函數(shù)沒有abstract,protected和sealed修飾符可以使用abstract,protected和sealed修飾符4.4.2接口1.接口介紹接口是用來(lái)定義一種程序的協(xié)定,它好比一種模版,定義了實(shí)現(xiàn)接口的對(duì)象必須實(shí)現(xiàn)的方法,其目的就是讓這些方法可以作為接口實(shí)例被引用。接口的定義如: publicinterfaceIPartA { voidSetDataA(stringdataA); }4.4.2接口【例4.14】接口演示。運(yùn)行結(jié)果如圖4.16所示:4.4.2接口接口允許多重繼承: interfaceID:IA,IB,IC { … } 類可以同時(shí)有一個(gè)基類和零個(gè)以上的接口,并要將基類寫在前面: classClassB:ClassA,IA,IB { … }4.4.2接口2.接口的實(shí)現(xiàn)指出接口成員所在的接口,則稱為顯式接口成員。上面程序接口實(shí)現(xiàn)可改寫成://沒有定義為publicvoidIPartA.SetDataA(stringdataA) { DataA=dataA; Console.WriteLine("{0}",DataA); }//沒有定義為publicvoidIPartB.SetDataB(stringdataB) { DataB=dataB; Console.WriteLine("{0}",DataB); }4.4.2接口顯式接口成員只能通過接口來(lái)調(diào)用。 classtest{ staticvoidMain() { SharedClassa=newSharedClass(); IPartBpartb=a; partb.SetDataA("interfaceIPartA"); partb.SetDataB("interfaceIPartB"); }}4.4.2接口【例4.15】顯式接口調(diào)用。運(yùn)行結(jié)果如圖4.17所示。4.5集合與索引器4.5.1集合1.自定義集合自定義集合是指實(shí)現(xiàn)System.Collections提供的集合接口的集合。下面以IEnumerable集合接口為例自定義集合。IEnumerable接口定義:publicinterfaceIEnumerable{IenumeratorGetEnumerator();}實(shí)現(xiàn)IEnumerable的同時(shí)也要實(shí)現(xiàn)IEnumerator接口。IEnumerator接口為:publicinterfaceIEnumerator{ objectCurrent {get(); } boolMoveNext(); voidReset();}4.5.1集合【例4.16】IEnumerable自定義集合。運(yùn)行結(jié)果如圖4.18所示。4.5.1集合2.使用集合類另一種使用集合的方法是使用系統(tǒng)已經(jīng)定義的集合類。下面就以Stack類為例介紹。Stack類表示對(duì)象的后進(jìn)先出集合。Stack類常用的方法有:Clear:從Stack中移除所有對(duì)象Pop:移除并返回位于Stack頂部的對(duì)象Push:將對(duì)象插入Stack的頂部Peek:返回位于Stack頂部的對(duì)象但不將其移除4.5.1集合【例4.17】Stack類的用法示例。運(yùn)行結(jié)果如圖4.19所示。4.5.2索引器【例4.18】索引器示例。運(yùn)行結(jié)果如圖4.20所示。4.5.2索引器【例4.19】包含計(jì)算和控制代碼的索引器。運(yùn)行結(jié)果如圖4.21所示。4.6異常處理4.6.1異常與異常類1.異常Win32API程序出現(xiàn)錯(cuò)誤時(shí),沒有使用異常處理機(jī)制作處理,大多數(shù)的Win32API都是通過返回bool值,用false來(lái)表示函數(shù)調(diào)用出了問題。COM用HRESULT來(lái)描述程序的運(yùn)行情況。當(dāng)HRESULT的高位為1,則表示一個(gè)假設(shè)被違反,HRESULT的其它位則可以幫助判斷問題的原因。請(qǐng)看下的代碼: 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。屬性訪問權(quán)限類型描述HelpLink只讀String獲取或設(shè)置指向此異常所關(guān)聯(lián)幫助文件的鏈接。InnerException只讀Exception獲取導(dǎo)致當(dāng)前異常的Exception實(shí)例。Message只讀String獲取描述當(dāng)前異常的消息。Source讀/寫String獲取或設(shè)置導(dǎo)致錯(cuò)誤的應(yīng)用程序或?qū)ο蟮拿Q。StackTrace只讀String獲取當(dāng)前異常發(fā)生所經(jīng)歷的方法的名稱和簽名。TargetSite只讀MethodBase獲取引發(fā)當(dāng)前異常的方法。4.6.1異常與異常類經(jīng)常使用的C#異常類見表4.6。異常類描述System.ArithmeticException在算術(shù)運(yùn)算期間發(fā)生的異常(如System.DivideByZeroException和System.OverflowException)的基類。System.ArrayTypeMismatchException當(dāng)存儲(chǔ)一個(gè)數(shù)組時(shí),如果由于被存儲(chǔ)的元素的實(shí)際類型與數(shù)組的實(shí)際類型不兼容而導(dǎo)致存儲(chǔ)失敗,就會(huì)引發(fā)此異常。System.DivideByZeroException在試圖用零除整數(shù)值時(shí)引發(fā)。System.IndexOutOfRangeException在試圖使用小于零或超出數(shù)組界限的下標(biāo)索引數(shù)組時(shí)引發(fā)。System.InvalidCastException當(dāng)從基類型或接口到派生類型的顯式轉(zhuǎn)換在運(yùn)行時(shí)失敗時(shí),就會(huì)引發(fā)此異常。System.NullReferenceException在需要使用引用對(duì)象的場(chǎng)合,如果使用null引用,就會(huì)引發(fā)此異常。System.OutOfMemoryException在分配內(nèi)存(通過new)的嘗試失敗時(shí)引發(fā)。System.OverflowException在checked上下文中的算術(shù)運(yùn)算溢出時(shí)引發(fā)。System.StackOverflowException當(dāng)執(zhí)行堆棧由于保存了太多掛起的方法調(diào)用而耗盡時(shí),就會(huì)引發(fā)此異常;這通常表明存在非常深或無(wú)限的遞歸。System.TypeInitializationException在靜態(tài)構(gòu)造函數(shù)引發(fā)異常并且沒有可以捕捉到它的catch子句時(shí)引發(fā)。4.6.2異常處理1.try語(yǔ)句將有可能發(fā)生異常的代碼作為try語(yǔ)句塊,處理try語(yǔ)句中出現(xiàn)的異常代碼放到catch語(yǔ)句塊。finally語(yǔ)句則是不管try語(yǔ)句中有沒有異常發(fā)生最后都要執(zhí)行其中的程序塊?!纠?.20】try-catch-finally語(yǔ)句示例。運(yùn)行結(jié)果如圖4.22所示。4.6.2異常處理catch塊中包含的是出現(xiàn)異常時(shí)要執(zhí)行的代碼。一個(gè)try后面可以有零個(gè)以上的catch塊。如果try塊中沒有異常,則catch塊中代碼不會(huì)被執(zhí)行。catch后面括號(hào)放入希望捕獲的異常,如例4.20中DivideByZeroException異常。當(dāng)兩個(gè)catch語(yǔ)句的異常類有派生關(guān)系的時(shí)候,要將包括派生的異常類catch語(yǔ)句放到前面,包括基類的catch語(yǔ)句放置到后面。finally塊包含了一定要執(zhí)行的代碼,通常是一些資源釋放,關(guān)閉文件等代碼?!纠?.21】多catch語(yǔ)句示例。運(yùn)行結(jié)果如圖4.23所示。4.6.2異常處理2.throw異常的發(fā)生有兩種可能:代碼執(zhí)行過程中滿足了異常的條件而使程序無(wú)法正常運(yùn)行下去;通過throw語(yǔ)句無(wú)條件拋出異常。第一種情況上面已經(jīng)介紹過了。第二種情況則與第一種情況完全相反,通過throw語(yǔ)句主動(dòng)在程序中拋出異常,拋出的異常要用catch語(yǔ)句捕獲,否則程序運(yùn)行將中斷。throw語(yǔ)句用法:throwexpressionthrow語(yǔ)句拋出的異常表達(dá)式expression必須表示一個(gè)System.Exception類型或它的派生類。4.6.2異常處理【例4.22】throw語(yǔ)句拋出異常。運(yùn)行結(jié)果如圖4.24所示。4.6.2異常處理throw語(yǔ)句重新拋出一個(gè)新的異常ArithmeticException,然后出由Main()中catch捕獲?!纠?.23】throw語(yǔ)句異常再次拋出。運(yùn)行結(jié)果如圖4.25所示。throw語(yǔ)句將Div()的DivideByZeroException再次拋出,由Main()中catch語(yǔ)句捕獲它。【例4.24】異常處理綜合舉例。4.7委托與事件4.7.1委托1.委托C#的委托相當(dāng)于在C/C++中的函數(shù)指針。函數(shù)指針用指針獲取一個(gè)函數(shù)的入口地址,實(shí)現(xiàn)對(duì)函數(shù)的操作。委托與C/C++中的函數(shù)指針不同在于委托是面向?qū)ο蟮?,是引用類型,因此?duì)委托的使用要先定義后實(shí)例化,最后才調(diào)用。定義委托使用關(guān)鍵字delegate,定義一個(gè)委托:delegateintSomeDelegate(intnID,stringsName);再實(shí)例化:SomeDelegated1=newSomeDelegate(wr.InstanceMethod);最后調(diào)用:d1(5,"aaa");通過委托SomeDelegate實(shí)現(xiàn)對(duì)方法InstanceMethod的調(diào)用,調(diào)用還必須有一個(gè)前提條件是:方法InstanceMethod有參數(shù)和定義SomeDelegate的參數(shù)一致,并且返回值為int。方法InstanceMethod定義:publicintInstanceMethod(intnID,stringsName)4.7.1委托【例4.25】委托示例。運(yùn)行結(jié)果如圖4.26所示。4.7.1委托2.多播相對(duì)于上面的一次委托只調(diào)用一個(gè)方法,一次委托也可以調(diào)用多個(gè)方法,稱為多播。通過+和-運(yùn)算符實(shí)現(xiàn)多播的增加或減少?!纠?.26】多播示例。運(yùn)行結(jié)果如圖4.27所示。4.7.1委托委托是從System.Delegate類派生而來(lái),多播則派生于System.Delegate的派生類System.MulticastDelegate,對(duì)于下面代碼:SomeDelegated3=d1+d2;也可以用Delegate.Combine方法寫成:SomeDelegated3=(SomeDelegate)Delegate.Combine(d1,d2);也可以使用MulticastDelegate.Combine的方法寫成:SomeDelegated3=(SomeDelegate)MulticastDelegate.Combine(d1,d2);4.7.2事件C#事件是按“發(fā)布-預(yù)訂”的方式工作。先在一個(gè)類中公布事件,然后就可以在任意數(shù)量的類中對(duì)事件預(yù)訂。事件的工作過程可以用圖4.28表示:4.7.2事件C#事件機(jī)制是基于委托實(shí)現(xiàn)的,因此要首先定義一個(gè)委托EventHandler:publicdelegatevoidEventHandler(objectfrom,myEventArgse)System.EventArgs是包含事件數(shù)據(jù)的類的基類,在代碼中可直接使用EventArgs類。myEventArgs類派生于EventArgs類,實(shí)現(xiàn)自定義事件數(shù)據(jù)的功能。這里from表示發(fā)生事件的對(duì)象。定義事件格式為:event事件的委托名事件名如事件TextOut定義:publiceventEventHandlerTextOut;事件的激活一般寫成:if(TextOut!=null) TextOut(this,newEventArgs());4.7.2事件檢查TextOut事件有沒有被訂閱,如不為null,則表示有用戶訂閱。訂閱事件的是TestApp類,首先實(shí)例化EventSource,然后訂閱事件:evsrc.TextOut+=newEventSource.EventHandler(CatchEvent);也可以取消訂閱:evsrc.TextOut-=newEventSource.EventHandler(CatchEvent);方法evsrc.TriggerEvent()激活事件,如果已經(jīng)訂閱了事件,則調(diào)用處理代碼,否則什么也沒有不執(zhí)行。4.7.2事件【例4.27】事件示例。運(yùn)行結(jié)果如圖4.29所示。4.8預(yù)處理命令4.8.1#define、#undef指令#define和#undef指令是用于定義符號(hào)和取消符號(hào)定義的預(yù)處理指令。#defineDEBUG#undefDEBUG這里定義和取消的符號(hào)是DEBUB。如果定義的符號(hào)已經(jīng)存在,#define則不起作用,同樣道理,如果符號(hào)不存在,#undef也就沒有任何作用。#define和#undef指令必須放于源程序的代碼之前。usingSystem;#defineDEBUG4.8.2#IF、#ELIF、#ELSE、#ENDIF指令#if、#elif、#else、#endif指令被用作條件編譯,它們類似于if/else結(jié)構(gòu)。#if和#elif后的標(biāo)識(shí)符表達(dá)式可以使用運(yùn)算符與(&&)、或(||)、非(!)。它們?cè)诔绦蛑薪Y(jié)構(gòu)如下所示:一條#if語(yǔ)句(必須有)零或多條#elif語(yǔ)句零或一條#else語(yǔ)句一條#endif語(yǔ)句(必須有)【例4.28】預(yù)處理示例。運(yùn)行結(jié)果如圖4.30所示。4.8.2#IF、#ELIF、#ELSE、#ENDIF指令當(dāng)執(zhí)行到#if語(yǔ)句,首先檢查DEBUG是否已經(jīng)定義,如果符號(hào)已經(jīng)定義,就編譯#if塊中的代碼,否則編譯#else塊中的代碼。#elif指令相當(dāng)于“elseif”?!纠?.29】#elif指令。運(yùn)行結(jié)果如圖4.31所示。4.8.3#WARNING、#ERROR指令#warning、#error指令用于產(chǎn)生警告或錯(cuò)誤。當(dāng)編譯器遇到#warning指令時(shí),會(huì)顯示#waring后面的文本,編譯還會(huì)繼續(xù)進(jìn)行。當(dāng)遇到#error指令時(shí),會(huì)顯示后面的文本,并終止編譯退出。這兩條指令可以用于檢查#define是否定義了什么不正確的符號(hào)。 #defineDEBUG #defineRELEASE #ifDEBUG #error你定義了DEBUG #endif #ifDEBUG&&RELEASE #warning你定義了DEBUG和RELEASE #endif4.8.4#REGION、#ENDREGION指令#region、#endregion指令用于標(biāo)識(shí)代碼塊。#regionOutVarmethod publicstaticvoidOutVar() { intvar=5; Console.WriteLine("varequals:{0}",var); } #endregion4.8.5#LINE指令#line指令用于改變編譯器在警告或錯(cuò)誤信息中顯示的文件名和行號(hào)信息。當(dāng)發(fā)生警告或錯(cuò)誤時(shí),不再顯示源程序中的實(shí)際位置,而是#line指定的行數(shù)。#line100 //指定行號(hào)為100#line200“test.cs” //test.cs替換原來(lái)的文件名作為編譯輸出文件名4.9組件與程序集4.9.1組件從軟件模型的角度考慮,人們將龐大的應(yīng)用程序分割成為多個(gè)模塊,每個(gè)模塊完成獨(dú)立的功能,模塊之間協(xié)同工作,這樣的模塊我們稱為組件。這些組件可以進(jìn)行單獨(dú)開發(fā),單獨(dú)編譯,單獨(dú)測(cè)試,把所有的組件組合在一起就得到了完整的系統(tǒng)。組件有不同方式的定義。范圍最廣的定義是組件包括二進(jìn)制代碼,也就是說它是可執(zhí)行的代碼,而不是未編譯的源代碼。DLL文件從這個(gè)意義上來(lái)說就是一種組件。較窄范圍的概念是組件提供一種手段,將內(nèi)容告訴其他程序,程序集具有這樣的功能。最嚴(yán)格的定義要求組件提供已知的接口,釋放不再使用的系統(tǒng)資源并提供與設(shè)計(jì)工具的集成功能。在.NET框架中,組件是指實(shí)現(xiàn)System.ComponentModel.IComponent接口的一個(gè)類,或從實(shí)現(xiàn)IComponent的類中直接或間接派生的類。.NET框架組件滿足這一要求。4.9.2程序集在安全問題上,.NET框架包含了代碼訪問安全(codeaccesssecurity)的新型安全模型。Windows安全是基于用戶的身份,代碼訪問安全則是基于程序集的標(biāo)識(shí),我們可以自己決定程序集的安全許可,如信任微軟發(fā)布的程序集,或者不信任何從網(wǎng)上下載的程序集,.NET框架為計(jì)算機(jī)中安裝內(nèi)容和運(yùn)行的程序有了更多的控制權(quán)。包含有一個(gè)文件的程序集的
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 一次函數(shù)知識(shí)點(diǎn)總結(jié)
- 一元一次不等式的解法(提高)知識(shí)講解
- 【高考政治必考知識(shí)點(diǎn)總結(jié)】高考政治知識(shí)點(diǎn)
- 雙輥式破碎機(jī)行業(yè)深度研究報(bào)告
- 【英語(yǔ)】英語(yǔ)總復(fù)習(xí)∶八年級(jí)英語(yǔ)上冊(cè)閱讀理解(提高)知識(shí)講解及答案經(jīng)典
- 物流園節(jié)能評(píng)估報(bào)告
- 2025年單滴行列式制瓶機(jī)項(xiàng)目可行性研究報(bào)告
- 2025年中國(guó)醫(yī)用干式激光相機(jī)行業(yè)發(fā)展監(jiān)測(cè)及投資前景展望報(bào)告
- 合伙合同范本個(gè)體
- 庭院配套銷售合同范本
- 變電站的電氣主接線課件
- 婦科運(yùn)用PDCA循環(huán)降低腹腔鏡術(shù)后腸脹氣的發(fā)生率品管圈成果匯報(bào)
- 新零售實(shí)務(wù)PPT完整全套教學(xué)課件
- 小學(xué)生1-6冊(cè)必背古詩(shī)楷書字帖(可直接打印-已排版)
- 基本電子電路裝調(diào)維修知識(shí)考試題庫(kù)(含答案)
- CLSIM100-S24英文版 抗菌藥物敏感性試驗(yàn)執(zhí)行標(biāo)準(zhǔn);第二十四版資料增刊
- 中國(guó)甲狀腺疾病診治指南
- 直腸癌臨床路徑表單
- 《中西醫(yī)的區(qū)別》課件
- 新員工培訓(xùn)結(jié)業(yè)考試
- GB/T 26018-2010高純鈷
評(píng)論
0/150
提交評(píng)論