深入理解C# 静态类与非静态类、静态成员的区别 [转载]
靜態(tài)類與非靜態(tài)類的重要區(qū)別在于靜態(tài)類不能實(shí)例化,也就是說(shuō),不能使用 new 關(guān)鍵字創(chuàng)建靜態(tài)類類型的變量。在聲明一個(gè)類時(shí)使用static關(guān)鍵字,具有兩個(gè)方面的意義:首先,它防止程序員寫代碼來(lái)實(shí)例化該靜態(tài)類;其次,它防止在類的內(nèi)部聲明任何實(shí)例字段或方法。
靜態(tài)類是自C# 2.0才引入的,C# 1.0不支持靜態(tài)類聲明。程序員必須聲明一個(gè)私有構(gòu)造器。私有構(gòu)造器禁止開發(fā)者在類的范圍之外實(shí)例化類的實(shí)例。使用私有構(gòu)造器的效果與使用靜態(tài)類的效果非常相似。
兩者的區(qū)別:
私有構(gòu)造器方式仍然可以從類的內(nèi)部對(duì)類進(jìn)行實(shí)例化,而靜態(tài)類禁止從任何地方實(shí)例化類,其中包括從類自身內(nèi)部。靜態(tài)類和使用私有構(gòu)造器的另一個(gè)區(qū)別在于,在 使用私有構(gòu)造器的類中,是允許有實(shí)例成員的,而C# 2.0和更高版本的編譯器不允許靜態(tài)類有任何實(shí)例成員。使用靜態(tài)類的優(yōu)點(diǎn)在于,編譯器能夠執(zhí)行檢查以確保不致偶然地添加實(shí)例成員,編譯器將保證不會(huì)創(chuàng)建此 類的實(shí)例。靜態(tài)類的另一個(gè)特征在于,C#編譯器會(huì)自動(dòng)把它標(biāo)記為sealed。這個(gè)關(guān)鍵字將類指定為不可擴(kuò)展;換言之,不能從它派生出其他類。
靜態(tài)類的主要特性:
1:僅包含靜態(tài)成員。
2:無(wú)法實(shí)例化。
3:是密封的。
4:不能包含實(shí)例構(gòu)造函數(shù)。
靜態(tài)成員
1:非靜態(tài)類可以包含靜態(tài)的方法、字段、屬性或事件;
2:無(wú)論對(duì)一個(gè)類創(chuàng)建多少個(gè)實(shí)例,它的靜態(tài)成員都只有一個(gè)副本;
3:靜態(tài)方法和屬性不能訪問其包含類型中的非靜態(tài)字段和事件,并且不能訪問任何對(duì)象的實(shí)例變量;
4:靜態(tài)方法只能被重載,而不能被重寫,因?yàn)殪o態(tài)方法不屬于類的實(shí)例成員;
5:雖然字段不能聲明為 static const,但 const 字段的行為在本質(zhì)上是靜態(tài)的。這樣的字段屬于類,不屬于類的實(shí)例。因此,可以同對(duì)待靜態(tài)字段一樣使用 ClassName.MemberName 表示法來(lái)訪問 const 字段;6:C# 不支持靜態(tài)局部變量(在方法內(nèi)部定義靜態(tài)變量)。
靜態(tài)構(gòu)造函數(shù)
1:靜態(tài)類可以有靜態(tài)構(gòu)造函數(shù),靜態(tài)構(gòu)造函數(shù)不可繼承;
2:靜態(tài)構(gòu)造函數(shù)可以用于靜態(tài)類,也可用于非靜態(tài)類;
3:靜態(tài)構(gòu)造函數(shù)無(wú)訪問修飾符、無(wú)參數(shù),只有一個(gè) static 標(biāo)志;
4:靜態(tài)構(gòu)造函數(shù)不可被直接調(diào)用,當(dāng)創(chuàng)建類實(shí)例或引用任何靜態(tài)成員之前,靜態(tài)構(gòu)造函數(shù)被自動(dòng)執(zhí)行,并且只執(zhí)行一次。
注意:
1:靜態(tài)類在內(nèi)存中是一直有位置的;
2:非靜態(tài)類在實(shí)例化后是在內(nèi)存中是獨(dú)立的,它的變量不會(huì)重復(fù),在使用后會(huì)及時(shí)銷毀,所以不會(huì)出現(xiàn)未知的錯(cuò)誤。在C#中靜態(tài)成員是比較敏感的東西,在不是十分確認(rèn)的情況下不要使用;
3:建議更多地使用一般類(非靜態(tài)類)。
使用選擇:
當(dāng)定義的類不需要進(jìn)行實(shí)例化時(shí),我們使用靜態(tài)類;如果需要實(shí)例化對(duì)象,需要繼承等特性時(shí),應(yīng)該使用非靜態(tài)類,并且將統(tǒng)一使用的變量和方法設(shè)為靜態(tài)的,那么所有實(shí)例對(duì)象都能訪問。
C# 靜態(tài)成員和方法的學(xué)習(xí)小結(jié)
數(shù)據(jù)成員:
數(shù)據(jù)成員可以分靜態(tài)變量、實(shí)例變量?jī)煞N.
靜態(tài)成員:靜態(tài)成員變量是和類相關(guān)聯(lián)的,可以作為類中"共"有的變量(是一個(gè)共性的表現(xiàn)),他不依賴特定對(duì)象的存在,訪問的時(shí)候通過(guò)類名加點(diǎn)操作符加變量名來(lái)訪問.
實(shí)例成員:實(shí)例成員變量是和對(duì)象相關(guān)聯(lián)的,訪問實(shí)例成員變量依賴于實(shí)例的存在.
函數(shù)成員:
方法可以主要分為靜態(tài)方法,實(shí)例方法
靜態(tài)方法:靜態(tài)方法是不屬于特定對(duì)象的方法,靜態(tài)方法可以訪問靜態(tài)成員變量,靜態(tài)方法不可以直接訪問實(shí)例變量,可以在實(shí)例函數(shù)調(diào)用的情況下,實(shí)例變 量做為參數(shù)傳給靜態(tài)方法。靜態(tài)方法也不能直接調(diào)用實(shí)例方法,可以間接調(diào)用,首先要?jiǎng)?chuàng)建一個(gè)類的實(shí)例,然后通過(guò)這一特定對(duì)象來(lái)調(diào)用靜態(tài)方法。
實(shí)例方法:一個(gè)實(shí)例方法的執(zhí)行與特定對(duì)象關(guān)聯(lián),他的執(zhí)行需要一個(gè)對(duì)象存在。實(shí)例方法可以直接訪問靜態(tài)變量和實(shí)例變量,實(shí)例方法可以直接訪問實(shí)例方 法、和靜態(tài)方法,靜態(tài)方法的訪問方式為類名加點(diǎn)操作符加變量名。當(dāng)多個(gè)實(shí)例對(duì)象存在時(shí),內(nèi)存中并不是存在美個(gè)特定的實(shí)例方法的拷貝,而是,相同類的所有對(duì) 象都共享每個(gè)實(shí)例方法的一個(gè)拷貝(實(shí)例方法只占用“一套”空間)。
?
如果將類中的某個(gè)成員聲明為static,則稱該成員為靜態(tài)成員。一般來(lái)說(shuō),靜態(tài)成員是屬于類所有的,而非靜態(tài)成員則屬于類的實(shí)例的。每創(chuàng)建一個(gè)類的實(shí) 例,都在內(nèi)存中為非靜態(tài)成員開辟一片區(qū)域。而類的靜態(tài)成員為類所有,為這個(gè)類的所有實(shí)例共享。無(wú)論這個(gè)類創(chuàng)建了多少副本,一個(gè)靜態(tài)成員在內(nèi)存中只占有一塊 區(qū)域。
C#類中靜態(tài)成員變量的生命周期問題,就是什么時(shí)候創(chuàng)建,什么時(shí)候銷毀已聲明元素的“生存期”是元素可供使用的時(shí)間周期。變量是唯一具有生存期的元 素;為此,編譯器將過(guò)程參數(shù)和函數(shù)返回值視為變量的特殊情況。變量的生存期表示它可以保留值的時(shí)間周期。在生存期內(nèi)變量的值可以更改,但變量總是保留某些 值。
不同的生存期
在模塊級(jí)聲明的變量通常在應(yīng)用程序的整個(gè)運(yùn)行期間都存在。在類或結(jié)構(gòu)中聲明的非共享變量作為聲明它的類或結(jié)構(gòu)的每個(gè)實(shí)例的單獨(dú)副本存在;每個(gè)這樣的變量都具有與它的實(shí)例相同的生存期。但是,Shared 變量?jī)H有一個(gè)生存期,即應(yīng)用程序運(yùn)行所持續(xù)的全部時(shí)間。
用 Dim 聲明的局部變量?jī)H當(dāng)聲明它們的過(guò)程正在執(zhí)行時(shí)存在。這同樣適用于過(guò)程的參數(shù)和任何函數(shù)返回值。但是,如果該過(guò)程調(diào)用其他過(guò)程,則局部變量在被調(diào)用過(guò)程運(yùn)行期間保留它們的值。
生存期的開始
當(dāng)執(zhí)行到聲明局部變量的過(guò)程時(shí),局部變量的生存期開始。過(guò)程一開始執(zhí)行,每個(gè)局部變量即被初始化為其數(shù)據(jù)類型的默認(rèn)值。數(shù)字變量(包括 Byte 和 Char)被初始化為 0,Date 變量初始化為公元 1 年的 1 月 1 日零時(shí),Boolean 變量初始化為 False,引用類型變量(包括字符串、數(shù)組和 Object)初始化為 Nothing。
結(jié)構(gòu)變量的每個(gè)成員被視為單獨(dú)的變量初始化。同樣,數(shù)組變量的每個(gè)元素也單獨(dú)初始化。
如果變量是用初始值設(shè)定項(xiàng)聲明的,則在執(zhí)行變量的聲明語(yǔ)句時(shí),將給該變量分配指定的值,如下面的示例所示:
Dim X As Double = 18.973 ' X had previously been initialized to 0.
在過(guò)程的內(nèi)部塊中聲明的變量在進(jìn)入該過(guò)程時(shí)初始化為其默認(rèn)值。不論該塊是否曾執(zhí)行過(guò),這些初始化都會(huì)生效。
生存期的結(jié)束
當(dāng)過(guò)程終止時(shí),不再保留該過(guò)程的局部變量值,并回收局部元素所使用的內(nèi)存。下次執(zhí)行該過(guò)程時(shí),將重新創(chuàng)建它的所有局部元素并初始化局部變量。
當(dāng)類或結(jié)構(gòu)的實(shí)例終止時(shí),它的非共享變量丟失它們的值。類或結(jié)構(gòu)的每個(gè)新實(shí)例都創(chuàng)建它的所有非共享元素并初始化非共享變量。Shared 元素被一直保留到應(yīng)用程序停止運(yùn)行時(shí)。
生存期的擴(kuò)展
如果局部變量是用 Static 關(guān)鍵字聲明的,則它的生存期比聲明它的過(guò)程的執(zhí)行時(shí)間長(zhǎng)。如果該過(guò)程在某模塊內(nèi),則只要應(yīng)用程序繼續(xù)運(yùn)行,static 變量就一直存在。
如果 static 變量是在類的內(nèi)部過(guò)程中聲明的,則該變量的生存期取決于此過(guò)程是否共享。如果此過(guò)程已用 Shared 關(guān)鍵字聲明,則變量的生存期將一直延續(xù)到應(yīng)用程序終止時(shí)為止。如果此過(guò)程為非共享,則其 static 變量為類的實(shí)例成員,并且其生存期與類實(shí)例的生存期相同。
在下面的示例中,RunningTotal 函數(shù)通過(guò)將新值添加到存儲(chǔ)在靜態(tài)變量 ApplesSold 中的以前值的合計(jì)來(lái)計(jì)算流量合計(jì):
?
Static ApplesSold As Integer
ApplesSold = ApplesSold + Num
Return ApplesSold ' ApplesSold keeps its current value.
End Function
?
如果沒有使用 Static 就已聲明了 ApplesSold,則在函數(shù)調(diào)用期間將不保留以前累計(jì)的值,并且函數(shù)只返回上次用來(lái)調(diào)用它的相同值。
在模塊級(jí)聲明 ApplesSold 可產(chǎn)生相同的生存期。但是,如果這樣更改變量的范圍,此過(guò)程將不再擁有對(duì)該變量的獨(dú)占訪問權(quán)。由于其他過(guò)程可以訪問該變量并更改它的值,因此流量合計(jì)是不可靠的,并且代碼可能會(huì)更難維護(hù)。
靜態(tài)成員在第一次被訪問之前并且在任何靜態(tài)構(gòu)造函數(shù)(如調(diào)用的話)之前初始化。若要訪問靜態(tài)類成員,應(yīng)使用類名而不是變量名來(lái)指定該成員的位置。
?
原文地址:http://www.cnblogs.com/answercard/p/4797492.html
轉(zhuǎn)載于:https://www.cnblogs.com/taiyonghai/p/7448056.html
總結(jié)
以上是生活随笔為你收集整理的深入理解C# 静态类与非静态类、静态成员的区别 [转载]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HALCON示例程序high.hdev使
- 下一篇: C#指定窗口显示位置的方法