版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
C#程序員面試必答1.靜態(tài)變量和非靜態(tài)變量的區(qū)別?答:靜態(tài)變量:靜態(tài)變量使用static修飾符進行聲明在所屬類被裝載時創(chuàng)建通過類進行訪問所屬類的所有實例的同一靜態(tài)變量都是同一個值非靜態(tài)變量:不帶有static修飾符聲明的變量稱做非靜態(tài)變量在類被實例化時創(chuàng)建通過對象進行訪問同一個類的不同實例的同一非靜態(tài)變量可以是不同的值示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample01{classProgram{classClass1{publicstaticStringstat(yī)icStr=&amp;quot;Class&amp;quot;;publicStringnotstaticStr=&amp;quot;Obj&amp;quot;;}staticvoidMain(string[]args){//靜態(tài)變量通過類進行訪問,該類所有實例的同一靜態(tài)變量都是同一個值Console.WriteLine(&amp;quot;Class1'sstaticStr:{0}&amp;quot;,Class1.staticStr);Class1tmpObj1=newClass1();tmpObj1.notstaticStr=&amp;quot;tmpObj1&;quot;;Class1tmpObj2=newClass1();tmpObj2.notstaticStr=&amp;quot;tmpObj2&amp;quot;;//非靜態(tài)變量通過對象進行訪問,不同對象的同一非靜態(tài)變量可以有不同的值Console.WriteLine(&amp;quot;tmpObj1'snotstaticStr:{0}&amp;quot;,tmpObj1.notstaticStr);Console.WriteLine(&amp;quot;tmpObj2'snotstaticStr:{0}";,tmpObj2.notstaticStr);Console.ReadLine();}}}復制代碼結果:Class1'sstaticStr:ClasstmpObj1'snotstaticStr:tmpObj1tmpObj2'snotstaticStr:tmpObj22.const和staticreadonly區(qū)別?答:const用const修飾符聲明的成員叫常量,是在編譯期初始化并嵌入到客戶端程序staticreadonly用staticreadonly修飾符聲明的成員仍然是變量,只但是具有和常量類似的使用方法:通過類進行訪問、初始化后不可以修改。但與常量不同的是這種變量是在運營期初始化示例:測試類:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample02Lib{publicclassClass1{publicconstStringstrConst=&amp;quot;Const&amp;quot;;publicstat(yī)icreadonlyStringstrStaticReadonly=&amp;quot;StaticReadonly&amp;quot;;//publicconstStringstrConst=&amp;quot;ConstChanged&amp;quot;;//publicstaticreadonlyStringstrStat(yī)icReadonly=&amp;quot;Stat(yī)icReadonlyChanged&amp;quot;;}//5-1-a-s-p-x}復制代碼客戶端代碼:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingExample02Lib;namespaceExample02{classProgram{staticvoidMain(string[]args){//修改Example02中Class1的strConst初始值后,只編譯Example02Lib項目//然后到資源管理器里把新編譯的Example02Lib.dll拷貝Example02.exe所在的目錄,執(zhí)行Example02.exe//切不可在IDE里直接調試運營由于這會重新編譯整個解決方案!!//可以看到strConst的輸出沒有改變,而strStaticReadonly的輸出已經改變//表白Const變量是在編譯期初始化并嵌入到客戶端程序,而StaticReadonly是在運營時初始化的Console.WriteLine(";strConst:{0}&amp;quot;,Class1.strConst);Console.WriteLine(&quot;strStaticReadonly:{0}&quot;,Class1.strStaticReadonly);Console.ReadLine();}}}復制代碼結果:strConst:ConststrStaticReadonly:StaticReadonly修改后的示例:測試類:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample02Lib{publicclassClass1{//publicconstStringstrConst=&amp;quot;Const&;quot;;//publicstaticreadonlyStringstrStat(yī)icReadonly=&amp;quot;StaticReadonly&amp;quot;;publicconstStringstrConst=&quot;ConstChanged&amp;quot;;publicstaticreadonlyStringstrStaticReadonly=&quot;StaticReadonlyChanged&amp;quot;;}}復制代碼結果strConst:ConststrStaticReadonly:Stat(yī)icReadonlyChanged3.extern是什么意思?答:extern修飾符用于聲明由程序集外部實現的成員函數經常用于系統(tǒng)API函數的調用(通過DllImport)。注意,和DllImport一起使用時要加上static修飾符也可以用于對于同一程序集不同版本組件的調用(用extern聲明別名)不能與abstract修飾符同時使用51aspx示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Runtime.InteropServices;namespaceExample03{classProgram{//注意DllImport是一個AttributeProperty,在System.Runtime.InteropServices命名空間中定義//extern與DllImport一起使用時必須再加上一個stat(yī)ic修飾符[DllImport(&;quot;User32.dll&amp;quot;)]publicstaticexternintMessageBox(intHandle,stringMessage,stringCaption,intType);staticintMain(){stringmyString;Console.Write(&;quot;Enteryourmessage:&amp;quot;);myString=Console.ReadLine();returnMessageBox(0,myString,&amp;quot;MyMessageBox&amp;quot;,0);}}}復制代碼結果:4.abstract是什么意思?答:abstract修飾符可以用于類、方法、屬性、事件和索引指示器(indexer),表達其為抽象成員abstract不可以和static、virtual、override一起使用聲明為abstract成員可以不涉及實現代碼,但只有類中尚有未實現的抽象成員,該類就不可以被實例化,通常用于強制繼承類必須實現某一成員示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample04{#region基類,抽象類publicabstractclassBaseClass{//抽象屬性,同時具有get和set訪問器表達繼承類必須將該屬性實現為可讀寫publicabstractStringAttribute{get;set;}//抽象方法,傳入一個字符串參數無返回值publicabstractvoidFunction(Stringvalue);//抽象事件,類型為系統(tǒng)預定義的代理(delegate):EventHandlerpublicabstracteventEventHandlerEvent;//抽象索引指示器,只具有get訪問器表達繼承類必須將該索引指示器實現為只讀publicabstractCharthis[intIndex]{get;}}#endregion#region繼承類publicclassDeriveClass:BaseClass{privateStringat(yī)tribute;publicoverrideStringAttribute{get{returnattribute;}set{attribute=value;}}publicoverridevoidFunction(Stringvalue){at(yī)tribute=value;if(Event!=null){Event(this,newEventArgs());}}publicoverrideeventEventHandlerEvent;publicoverrideCharthis[intIndex]{get{returnattribute[Index];}}}#endregionclassProgram{staticvoidOnFunction(objectsender,EventArgse){for(inti=0;i<((DeriveClass)sender).Attribute.Length;i++){Console.WriteLine(((DeriveClass)sender)[i]);}}staticvoidMain(string[]args){DeriveClasstmpObj=newDeriveClass();tmpObj.Attribute=&amp;quot;1234567&quot;;Console.WriteLine(tmpObj.Attribute);//將靜態(tài)函數OnFunction與tmpObj對象的Event事件進行關聯tmpObj.Event+=newEventHandler(OnFunction);tmpObj.Function(&amp;quot;7654321");Console.ReadLine();}}}復制代碼結果:123456776543215.internal修飾符起什么作用?答:internal修飾符可以用于類型或成員,使用該修飾符聲明的類型或成員只能在同一程集內訪問接口的成員不能使用internal修飾符示例Example05Lib項目的Class1usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample05Lib{publicclassClass1{internalStringstrInternal=null;publicStringstrPublic;}}復制代碼結果Example05Lib項目的Class2類可以訪問到Class1的strInternal成員Example05項目的Program類無法訪問到Class1的strInternal成員6.sealed修飾符是干什么的?答:sealed修飾符表達密封用于類時,表達該類不能再被繼承,不能和abstract同時使用,由于這兩個修飾符在含義上互相排斥用于方法和屬性時,表達該方法或屬性不能再被繼承,必須和override關鍵字一起使用,由于使用sealed修飾符的方法或屬性肯定是基類中相應的虛成員通常用于實現第三方類庫時不想被客戶端繼承,或用于沒有必要再繼承的類以防止濫用繼承導致層次結構體系混亂恰當的運用sealed修飾符也可以提高一定的運營效率,由于不用考慮繼承類會重寫該成員示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample06{classProgram{classA{publicvirtualvoidF(){Console.WriteLine(&amp;quot;A.F&quot;);}publicvirtualvoidG(){Console.WriteLine(&quot;A.G&amp;quot;);}}classB:A{publicsealedoverridevoidF(){Console.WriteLine(&amp;quot;B.F&quot;);}publicoverridevoidG(){Console.WriteLine(&;quot;B.G&quot;);}}classC:B{publicoverridevoidG(){Console.WriteLine(&amp;quot;C.G";);}}staticvoidMain(string[]args){newA().F();newA().G();newB().F();newB().G();newC().F();newC().G();Console.ReadLine();}}}復制代碼結果:類B在繼承類A時可以重寫兩個虛函數,如圖所示:由于類B中對F方法進行了密封,類C在繼承類B時只能重寫一個函數,如圖所示:控制臺輸出結果,類C的方法F只能是輸出類B中對該方法的實現:A.FA.GB.FB.GB.FC.G7.override和overload的區(qū)別?答:override表達重寫,用于繼承類對基類中虛成員的實現overload表達重載,用于同一個類中同名方法不同參數(涉及類型不同或個數不同)的實現示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample07{classProgram{classBaseClass{publicvirtualvoidF(){Console.WriteLine(&;quot;BaseClass.F&;quot;);}}classDeriveClass:BaseClass{publicoverridevoidF(){base.F();Console.WriteLine(&amp;quot;DeriveClass.F&amp;quot;);}publicvoidAdd(intLeft,intRight){Console.WriteLine(&amp;quot;AddforInt:{0}&amp;quot;,Left+Right);}publicvoidAdd(doubleLeft,doubleRight){Console.WriteLine(&amp;quot;Addforint:{0}&amp;quot;,Left+Right);}}staticvoidMain(string[]args){DeriveClasstmpObj=newDeriveClass();tmpObj.F();tmpObj.Add(1,2);tmpObj.Add(1.1,2.2);Console.ReadLine();}}}復制代碼結果:BaseClass.FDeriveClass.FAddforInt:3Addforint:3.38.什么是索引指示器?答:實現索引指示器(indexer)的類可以象數組那樣使用其實例后的對象,但與數組不同的是索引指示器的參數類型不僅限于int簡樸來說,其本質就是一個含參數屬性示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample08{publicclassPoint{privatedoublex,y;publicPoint(doubleX,doubleY){x=X;y=Y;}//重寫ToString方法方便輸出publicoverridestringToString(){returnString.Format(&amp;quot;X:{0},Y:{1}&amp;quot;,x,y);}}publicclassPoints{Point[]points;publicPoints(Point[]Points){points=Points;}publicintPointNumber{get{returnpoints.Length;}}//實現索引訪問器publicPointthis[intIndex]{get{returnpoints[Index];}}}//感謝watsonhua()的指點//索引指示器的實質是含參屬性,參數并不只限于intclassWeatherOfWeek{publicstringthis[intIndex]{get{//注意case段使用return直接返回所以不需要breakswitch(Index){case0:{return"Todayiscloudy!&amp;quot;;}case5:{return&amp;quot;Todayisthundershower!&amp;quot;;}default:{return&amp;quot;Todayisfine!&amp;quot;;}}}}publicstringthis[stringDay]{get{stringTodayWeather=null;//switch的標準寫法switch(Day){case&amp;quot;Sunday&amp;quot;:{TodayWeather=&amp;quot;Todayiscloudy!&amp;quot;;break;}case&quot;Friday&amp;quot;:{TodayWeat(yī)her=&amp;quot;Todayisthundershower!&amp;quot;;break;}default:{TodayWeather=&quot;Todayisfine!";;break;}}returnTodayWeather;}}}classProgram{staticvoidMain(string[]args){Point[]tmpPoints=newPoint[10];for(inti=0;i<tmpPoints.Length;i++){tmpPoints[i]=newPoint(i,Math.Sin(i));}PointstmpObj=newPoints(tmpPoints);for(inti=0;i<tmpObj.PointNumber;i++){Console.WriteLine(tmpObj[i]);}string[]Week=newstring[]{&amp;quot;Sunday",&quot;Monday&amp;quot;,";Tuesday&amp;quot;,&amp;quot;Wednesday&quot;,&amp;quot;Thursday&amp;quot;,&amp;quot;Friday&quot;,&amp;quot;Staurday&quot;};WeatherOfWeektmpWeatherOfWeek=newWeatherOfWeek();for(inti=0;i<6;i++){Console.WriteLine(tmpWeat(yī)herOfWeek[i]);}foreach(stringtmpDayinWeek){Console.WriteLine(tmpWeatherOfWeek[tmpDay]);}Console.ReadLine();}}}復制代碼結果:X:0,Y:0X:1,Y:0.8497X:2,Y:0.682X:3,Y:0.9867X:4,Y:-0.928X:5,Y:-0.138X:6,Y:-0.2794X:7,Y:0.789X:8,Y:0.382X:9,Y:0.4121Todayiscloudy!Todayisfine!Todayisfine?。詏dayisfine!Todayisfine?。詏dayisthundershower!Todayiscloudy!Todayisfine!Todayisfine!Todayisfine!Todayisfine!Todayisthundershower!Todayisfine!9.new修飾符是起什么作用?答:new修飾符與new操作符是兩個概念new修飾符用于聲明類或類的成員,表達隱藏了基類中同名的成員。而new操作符用于實例化一個類型new修飾符只能用于繼承類,一般用于填補基類設計的局限性new修飾符和override修飾符不可同時用在一個成員上,由于這兩個修飾符在含義上互相排斥示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample09{classBaseClass{//基類設計者聲明了一個PI的公共變量,方便進行運算publicstaticdoublePI=3.1415;}classDervieClass:BaseClass{//繼承類發(fā)現該變量的值不能滿足運算精度,于是可以通過new修飾符顯示隱藏基類中的聲明publicnewstaticdoublePI=3.1415926;}classProgram{staticvoidMain(string[]args){Console.WriteLine(BaseClass.PI);Console.WriteLine(DervieClass.PI);Console.ReadLine();}}}復制代碼結果:3.14153.141592610.this關鍵字的含義?答:this是一個保存字,僅限于構造函數和方法成員中使用在類的構造函數中出現表達對正在構造的對象自身的引用,在類的方法中出現表達對調用該方法的對象的引用,在結構的構造上函數中出現表達對正在構造的結構的引用,在結構的方法中出現表達對調用該方法的結果的引用this保存字不能用于靜態(tài)成員的實現里,由于這時對象或結構并未實例化在C#系統(tǒng)中,this事實上是一個常量,所以不能使用this++這樣的運算this保存字一般用于限定同名的隱藏成員、將對象自身做為參數、聲明索引訪問器、判斷傳入參數的對象是否為自身示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample10{classClass1{privatedoublec;privatestringvalue;publicdoubleC{get{returnc;}}publicClass1(doublec){//限定同名的隱藏成員this.c=c;}publicClass1(Class1value){//用對象自身實例化自己沒故意義if(this!=value){c=value.C;}}publicoverridestringToString(){//將對象自身做為參數returnstring.Format(&quot;{0}Celsius={1}Fahrenheit",c,UnitTransClass.C2F(this));}//由于好奇,在這做了一個效率測試,想看看到底哪種方式訪問成員變量更快,結論:區(qū)別不大。。。publicstringTest1(){longvTickCount=Environment.TickCount;for(inti=0;i<10000000;i++)this.value=i.ToString();returnstring.Format(yī)(&amp;quot;Havethis.:{0}MSEL&amp;quot;,Environment.TickCount-vTickCount);}publicstringTest2(){longvTickCount=Environment.TickCount;for(inti=0;i<10000000;i++)value=i.ToString();returnstring.Format(&amp;quot;Don'thavethis.:{0}MSEL&amp;quot;,Environment.TickCount-vTickCount);}}classUnitTransClass{publicstat(yī)icdoubleC2F(Class1value){//攝氏到華氏的轉換公式return1.8*value.C+32;}}classProgram{staticvoidMain(string[]args){Class1tmpObj=newClass1(37.5);Console.WriteLine(tmpObj);Console.WriteLine(tmpObj.Test1());Console.WriteLine(tmpObj.Test2());Console.ReadLine();}}}復制代碼結果:37.5Celsius=99.5FahrenheitHavethis.:4375MSELDon'thavethis.:4406MSEL11.可以使用抽象函數重寫基類中的虛函數嗎?答:可以,但需使用new修飾符顯式聲明,表達隱藏了基類中該函數的實現示例:classBaseClass{publicvirtualvoidF(){Console.WriteLine(&quot;BaseClass.F&;quot;);}}abstractclassDeriveClass:BaseClass{publicnewabstractvoidF();}復制代碼12.密封類可以有虛函數嗎?答:可以,基類中的虛函數將隱式的轉化為非虛函數,但密封類自身不能再增長新的虛函數示例:classBaseClass{publicvirtualvoidF(){Console.WriteLine(&quot;BaseClass.F&quot;);}}sealedclassDeriveClass:BaseClass{//基類中的虛函數F被隱式的轉化為非虛函數//密封類中不能再聲明新的虛函數G//publicvirtualvoidG()//{//Console.WriteLine(&amp;quot;DeriveClass.G&;quot;);//}}復制代碼13.假如基類中的虛屬性只有一個屬性訪問器,那么繼承類重寫該屬性后可以有幾個屬性訪問器?假如基類中有get和set兩個呢?答:假如基類中的虛屬性只有一個屬性訪問器,那么繼承類重寫該屬性后也應只有一個。假如基類中有get和set兩個屬性訪問器,那么繼承類中可以只有一個也可以同時有兩個屬性訪問器14.abstract可以和virtual一起使用嗎?可以和override一起使用嗎?答:abstract修飾符不可以和static、virtual和override修飾符一起使用15.接口可以包含哪些成員?答:接口可以包含屬性、方法、索引指示器和事件,但不能包含常量、域、操作符、構造函數和析構函數,并且也不能包含任何靜態(tài)成員16.類和結構的區(qū)別?答:類:類是引用類型在堆上分派,類的實例進行賦值只是復制了引用,都指向同一段實際對象分派的內存類有構造和析構函數類可以繼承和被繼承結構:結構是值類型在棧上分派(雖然棧的訪問速度比較堆要快,但棧的資源有限放),結構的賦值將分派產生一個新的對象。結構沒有構造函數,但可以添加。結構沒有析構函數結構不可以繼承自另一個結構或被繼承,但和類同樣可以繼承自接口示例:根據以上比較,我們可以得出一些輕量級的對象最佳使用結構,但數據量大或有復雜解決邏輯對象最佳使用類。如:Geoemtry(GIS里的一個概論,在OGC標準里有定義)最佳使用類,而Geometry中點的成員最佳使用結構usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample16{interfaceIPoint{doubleX{get;set;}doubleY{get;set;}doubleZ{get;set;}}//結構也可以從接口繼承structPoint:IPoint{privat(yī)edoublex,y,z;//結構也可以增長構造函數publicPoint(doubleX,doubleY,doubleZ){this.x=X;this.y=Y;this.z=Z;}publicdoubleX{get{returnx;}set{x=value;}}publicdoubleY{get{returnx;}set{x=value;}}publicdoubleZ{get{returnx;}set{x=value;}}}//在此簡化了點狀Geometry的設計,實際產品中還包含Project(坐標變換)等復雜操作classPointGeometry{privatePointvalue;publicPointGeometry(doubleX,doubleY,doubleZ){value=newPoint(X,Y,Z);}publicPointGeometry(Pointvalue){//結構的賦值將分派新的內存this.value=value;}publicdoubleX{get{returnvalue.X;}set{this.value.X=value;}}publicdoubleY{get{returnvalue.Y;}set{this.value.Y=value;}}publicdoubleZ{get{returnvalue.Z;}set{this.value.Z=value;}}publicstat(yī)icPointGeometryoperat(yī)or+(PointGeometryLeft,PointGeometryRigth){returnnewPointGeometry(Left.X+Rigth.X,Left.Y+Rigth.Y,Left.Z+Rigth.Z);}publicoverridestringToString(){returnstring.Format(&amp;quot;X:{0},Y:{1},Z:{2}&amp;quot;,value.X,value.Y,value.Z);}}classProgram{staticvoidMain(string[]args){PointtmpPoint=newPoint(1,2,3);PointGeometrytmpPG1=newPointGeometry(tmpPoint);PointGeometrytmpPG2=newPointGeometry(tmpPoint);tmpPG2.X=4;tmpPG2.Y=5;tmpPG2.Z=6;//由于結構是值類型,tmpPG1和tmpPG2的坐標并不同樣Console.WriteLine(tmpPG1);Console.WriteLine(tmpPG2);//由于類是引用類型,對tmpPG1坐標修改后影響到了tmpPG3PointGeometrytmpPG3=tmpPG1;tmpPG1.X=7;tmpPG1.Y=8;tmpPG1.Z=9;Console.WriteLine(tmpPG1);Console.WriteLine(tmpPG3);Console.ReadLine();}}}復制代碼結果:X:1,Y:2,Z:3X:4,Y:5,Z:6X:7,Y:8,Z:9X:7,Y:8,Z:917.接口的多繼承會帶來哪些問題?答:C#中的接口與類不同,可以使用多繼承,即一個子接口可以有多個父接口。但假如兩個父成員具有同名的成員,就產生了二義性(這也正是C#中類取消了多繼承的因素之一),這時在實現時最佳使用顯式的聲明示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample17{classProgram{//一個完整的接口聲明示例interfaceIExample{//屬性stringP{get;set;}//方法stringF(intValue);//事件eventEventHandlerE;//索引指示器stringthis[intIndex]{get;set;}}interfaceIA{intCount{get;set;}}interfaceIB{intCount();}//IC接口從IA和IB多重繼承interfaceIC:IA,IB{}classC:IC{privateintcount=100;//顯式聲明實現IA接口中的Count屬性intIA.Count{get{return100;}set{count=value;}}//顯式聲明實現IB接口中的Count方法intIB.Count(){returncount*count;}}stat(yī)icvoidMain(string[]args){CtmpObj=newC();//調用時也要顯式轉換Console.WriteLine(&amp;quot;Countproperty:{0}&quot;,((IA)tmpObj).Count);Console.WriteLine(&quot;Countfunction:{0}&amp;quot;,((IB)tmpObj).Count());Console.ReadLine();}}}復制代碼結果:Countproperty:100Countfunction:1000018.抽象類和接口的區(qū)別?答:抽象類(abstractclass)可以包含功能定義和實現,接口(interface)只能包含功能定義抽象類是從一系列相關對象中抽象出來的概念,因此反映的是事物的內部共性;接口是為了滿足外部調用而定義的一個功能約定,因此反映的是事物的外部特性分析對象,提煉內部共性形成抽象類,用以表達對象本質,即“是什么”為外部提供調用或功能需要擴充時優(yōu)先使用接口19.別名指示符是什么?答:通過別名指示符我們可認為某個類型起一個別名重要用于解決兩個命名空間內有同名類型的沖突或避免使用冗余的命名空間別名指示符只在一個單元文獻內起作用示例:Class1.cs:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespacecom.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01{classClass1{publicoverridestringToString(){return"com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01'sClass1&amp;quot;;}}}復制代碼Class2.csusingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespacecom.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02{classClass1{publicoverridestringToString(){return&amp;quot;com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02'sClass1&amp;quot;;}}}復制代碼主單元(Program.cs):usingSystem;usingSystem.Collections.Generic;usingSystem.Text;//使用別名指示符解決同名類型(51aspx)的沖突usingLib01Class1=com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01.Class1;usingLib02Class2=com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02.Class1;namespaceExample19{classProgram{staticvoidMain(string[]args){Lib01Class1tmpObj1=newLib01Class1();Lib02Class2tmpObj2=newLib02Class2();Console.WriteLine(tmpObj1);Console.WriteLine(tmpObj2);Console.ReadLine();}}}復制代碼結果:com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01'sClass1com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02'sClass120.如何釋放非托管資源?答:.NET平臺在內存管理方面提供了GC(GarbageCollection),負責自動釋放托管資源和內存回收的工作,但它無法對非托管資源進行釋放,這時我們必須自己提供方法來釋放對象內分派的非托管資源,比如你在對象的實現代碼中使用了一個COM對象最簡樸的辦法,可以通過實現protectedvoidFinalize()(析構函數會在編譯時變成這個東東)來釋放非托管資源,由于GC在釋放對象時會檢查該對象是否實現了Finalize()方法,假如是則調用它。但,據說這樣會減少效率。。。有一種更好的,那就是通過實現一個接口顯式的提供應客戶調用端手工釋放對象的方法,而不是傻傻的等著GC來釋放我們的對象(何況效率又那么低)System命名空間內有一個IDisposable接口,拿來做這事非常合適,就免得我們自己再聲明一個接口了此外補充一句,這種實現并不一定要使用了非托管資源后才用,假如你設計的類會在運營時有大些的實例(象GIS中的Geometry),為了優(yōu)化程序性能,你也可以通過實現該接口讓客戶調用端在確認不需要這些對象時手工釋放它們示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample20{classProgram{classClass1:IDisposable{//析構函數,編譯后變成protectedvoidFinalize(),GC會在回收對象前會調用調用該方法~Class1(){Dispose(false);}//通過實現該接口,客戶可以顯式地釋放對象,而不需要等待GC來釋放資源,據說那樣會減少效率voidIDisposable.Dispose(){Dispose(true);}//將釋放非托管資源設計成一個虛函數,提供在繼承類中釋放基類的資源的能力protectedvirtualvoidReleaseUnmanageResources(){//Dosomething...}//私有函數用以釋放非托管資源privatevoidDispose(booldisposing){ReleaseUnmanageResources();//為true時表達是客戶顯式調用了釋放函數,需告知GC不要再調用對象的Finalize方法//為false時肯定是GC調用了對象的Finalize方法,所以沒有必要再告訴GC你不要調用我的Finalize方法啦if(disposing){GC.SuppressFinalize(this);}}}staticvoidMain(string[]args){//tmpObj1沒有手工釋放資源,就等著GC來慢慢的釋放它吧Class1tmpObj1=newClass1();//tmpObj2調用了Dispose方法,傳說比等著GC來釋放它效率要調一些//個人認為是由于要逐個對象的查看其元數據,以確認是否實現了Dispose方法吧//當然最重要的是我們可以自己擬定釋放的時間以節(jié)省內存,優(yōu)化程序運營效率Class1tmpObj2=newClass1();((IDisposable)tmpObj2).Dispose();}}}復制代碼21.P/Invoke是什么?答:在受控代碼與非受控代碼進行交互時會產生一個事務(transition),這通常發(fā)生在使用平臺調用服務(PlatformInvocationServices),即P/Invoke如調用系統(tǒng)的API或與COM對象打交道,通過System.Runtime.InteropServices命名空間雖然使用Interop非常方便,但據估計每次調用事務都要執(zhí)行10到40條指令,算起來開銷也不少,所以我們要盡量少調用事務假如非用不可,建議本著一次調用執(zhí)行多個動作,而不是多次調用每次只執(zhí)行少量動作的原則22.StringBuilder和String的區(qū)別?答:String雖然是一個引用類型,但在賦值操作時會產生一個新的對象,而StringBuilder則不會所以在大量字符串拼接或頻繁對某一字符串進行操作時最佳使用StringBuilder,不要使用String示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExample22{classProgram{staticvoidMain(string[]args){constintcycle=100000;longvTickCount=Environment.TickCount;Stringstr=null;for(inti=0;i<cycle;i++)str+=i.ToString();Console.WriteLine(&;quot;String:{0}MSEL&amp;quot;,Environment.TickCount-vTickCount);vTickCount=Environment.TickCount;//看到這個變量名我就氣憤,奇怪為什么大家都使它呢?:)StringBuildersb=newStringBuilder();for(inti=0;i<cycle;i++)sb.Append(i);Console.WriteLine(&amp;quot;StringBuilder:{0}MSEL&quot;,Environment.TickCount-vTickCount);Console.ReadLine();}}}復制代碼結果:String:102047MSELStringBuilder:46MSEL23.explicit和implicit的含義?答:explicit和implicit屬于轉換運算符,如用這兩者可以讓我們自定義的類型支持互相互換explicti表達顯式轉換,如從A->B必須進行強制類
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 監(jiān)控服務合同的變更與終止情形探討
- 房屋買賣合同的監(jiān)管與維權
- 營業(yè)執(zhí)照轉讓合同文本
- 企業(yè)保全服務合同范本
- 電力工程分包合同協(xié)議
- 內部勞務分包合同糾紛的解決方法
- 房屋買賣合同詳盡指南
- 水果供應商采購合同模板
- 瓷磚促銷活動購銷合同
- 不銹鋼購銷合同范本
- 第5章 自動駕駛技術
- 國開經濟法律基礎形考任務國開電大《經濟法律基礎》形考任務3答案
- 水質監(jiān)測運維方案樣本
- 生命教育三年級下冊
- 五金產品檢驗作業(yè)指導書
- 高壓旋噴樁檢測方案
- Unit1 My classroom Part A Lets spell(說課稿)-2022-2023學年英語四年級上冊
- 【要點解讀】《實踐是檢驗真理的唯一標準》論證邏輯圖
- 商務禮儀(山東聯盟)知到章節(jié)答案智慧樹2023年山東財經大學
- 跳繩興趣小組活動總結
- 文物保護項目加固工程監(jiān)理細則
評論
0/150
提交評論