c#基礎

1.值類型和引用類型的區(qū)別

? ??????I.簡單比較:

? ? ? ? 值類型的變量直接存儲數據,引用類型的變量持有的是數據的引用,數據存儲在數據堆中。

? ? ? ? 值類型(value?type):byte,short,int,long,float,double,char,bool,struct,decimal都是值類型。值類型變量聲明后,不管是否已經賦值,編譯器為其分配內存。

? ? ? ? 引用類型(reference type):string?和class統(tǒng)稱為引用類型。當聲明一個類時,只在棧中分配一小片內存用于容納一個地址,而此時并沒有為其分配堆上的內存空間。當使用new創(chuàng)建一個類的實例時,分配堆上的空間,并把堆上空間的地址保存到棧上分配的小片空間中。

? ? ? ? 值類型的實例通常是在線程棧上分配的(靜態(tài)分配),但是某些情況下可以存儲在堆中(如果值類型是引用類型的成員變量,則跟隨引用類型,存儲在堆上。)。引用類型的對象總是在進程堆中分配(動態(tài)分配)。?

? ? ? ? 值類型存儲在內存堆上示例:


值類型是引用類型的成員變量
值類型跟隨引用對象存儲在堆中

? ? ? ? II.相同點

? ? ? ? 引用類型可以實現接口,值類型中的結構體也可以實現接口

? ? ? ? 引用類型和值類型都繼承自System.Object類(值類型繼承自System.ValueType,隱試繼承自System.Object)

? ? ? ? III.不同點

? ? ? ??1)范圍方面

? ? ? ? c#的值類型包括:結構體(數據類型、bool型、用戶定義的結構體),枚舉,可空類型。

? ? ? ? c#的引用類型包括:數組,用戶定義的類,接口,委托,object,字符串。

? ? ? ? 2)內存分配方面

? ? ? ? 數組的元素不管是引用類型還是值類型,都存儲在托管堆上。

? ? ? ? 引用類型在棧中存儲一個引用,其實際的存儲位置位于托管堆。簡稱引用類型部署在托管堆上。而值類型總是分配在它聲明的地方:作為字段是,跟隨其所屬的變量(實例)存儲;作為局部變量時,存儲在棧上。(棧的內存是自動釋放的,堆內存是.NET中會由GC來自動釋放)

? ? ? ? 3)適用場合

? ? ? ? 值類型在內存管理方面具有更好的效率,并且不支持多態(tài),適合用作存儲數據的載體;引用類型支持多態(tài),適合用于定義應用程序的行為。

? ? ? ? 引用類型可以派生出新的類型,而值類型不能,因為所有的值類型都是密封的(seal);

? ? ? ? 引用類型可以包含null值,值類型不能(可空類型功能允許將null賦給值類型,如int? a = null;);

? ? ? ? 引用類型變量的賦值只賦值對象的引用,而不復制對象本身。而將一個值類型變量賦給另一個值類型變量時,將復制包含的值。(當然,兩者賦值變量的改變不會改變原變量的值)

2.字節(jié)

? ? ? ? 字節(jié)(byte)是計算機信息技術用于計量存儲容量的一種計量單位,通常情況下一字節(jié)等于八位,也在一些計算機編程語言中表示數據類型和語言字符。

? ? ? ? I.B與bit

? ? ? ? 數據存儲是以字節(jié)(Byte)為單位,數據傳輸大多是以位(bit,又名比特)為單位,一個位就代表一個0或1(即二進制),每8個位(bit,簡寫為b)組成一個字節(jié)(Byte,簡寫為B),是最小一級的信息單位。

? ? ? ? II.8中基本數據類型占字節(jié)數


3.抽象函數、虛函數、接口、抽象類

I.抽象函數

? ? ? ? 抽象方法必須聲明在抽象類中,聲明抽象方法時,不能使用virtual、static、private修飾符。在抽象類中抽象方法不提供實現。抽象方法不包含方法主體,必須由派生類以override方式實現此放方法。

II.虛函數

? ? ? ? 虛函數在編譯期間是不被靜態(tài)編譯的,它的相對地址不不確定的,它會根據運行時對象實例來動態(tài)判斷要調用的函數,其中那個申明是定義的類叫申明類,那個執(zhí)行時實例化的類叫實例類。

? ? ? ? 當調用一個對象的函數時,系統(tǒng)會直接去檢查這個對象申明定義的類,即申明類,看所調用的函數是否為虛函數;如果不是虛函數,那么就直接執(zhí)行該函數。而如果有virtual關鍵字,也就是一個虛函數,那么這個時候它就不會立刻執(zhí)行該函數,而是轉去檢查對象的實例類,是否重新實現了該虛函數,如果重新實現,它就不會再找了,而馬上執(zhí)行該實例類中這個重新實現的函數。如果沒有,系統(tǒng)就會不停地往上找實例類,并對父類重復剛才在實例類里的檢查,直到找到了第一個重寫了該虛函數的父類位置,然后執(zhí)行該父類里重寫的函數。

????????一般函數在編譯時就靜態(tài)地編譯到了執(zhí)行文件中,其相對地址在程序運行期間是不發(fā)生變化的,也就是寫死了的。

III.接口

接口是指定一組函數成員而不實現成員的引用類型,其他類型和接口可以繼承接口,接口主要有以下特點:

1)通過接口可以實現多重繼承,c#接口的成員不能有public、protected、internal、private等修飾符。原因是接口里面的方法都需要由外面接口實現去實現方法體,所以修飾符必須是public。

2)接口成員不能有new、static、abstract、override、virtual修飾符(當一個接口實現一個接口,這兩個接口有相同的方法時,可以使用new關鍵字隱藏父接口中的方法)。

3)接口中只包含成員的簽名,接口沒有構造函數,所有不能直接使用new對接口進行實例化。接口中只能包含方法、屬性、事件和索引的組合。接口一旦被實現,實現類必須實現接口中所有成員,除非實現類本身是抽象類。??

4)接口可以被多繼承

IV.抽象類 ? ?

? ? ? ? 不能被初始化的類被叫做抽象類,它們只提供部分實現,但是另一個類可以繼承它并且能創(chuàng)建他們的實例。抽象類能夠被用于類、方法、屬性、索引器和事件,使用abstract在一個類聲明中表示該類時抽象類,由其派生類實現。抽象類不能被封閉。


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容