深入c# 類和結(jié)構(gòu)的區(qū)別總結(jié)詳解
更新時(shí)間:2013年05月22日 18:04:27 作者:
本篇文章是對c#中類和結(jié)構(gòu)的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
類和結(jié)構(gòu)的區(qū)別:
1.一個(gè)是引用類型一個(gè)是值類型
Class是引用類型,繼承自System.Object類
Struct是值類型,繼承自System.ValueType類,因此不具有多態(tài)性
因?yàn)榻Y(jié)構(gòu)是值類型,所以結(jié)構(gòu)之間賦值可以創(chuàng)建新的結(jié)構(gòu),復(fù)制包含結(jié)構(gòu)的變量時(shí),講復(fù)制所有的數(shù)據(jù),對新的副本所作的修改都不會改變舊副本的數(shù)據(jù),而類是引用類型,類之間的賦值只是復(fù)制引用。
2. 繼承性的區(qū)別
Class支持繼承,可以繼承自類和接口,是完全可擴(kuò)展的,除非聲明sealed。否則類可以繼承自其它的類的接口,自身也能被繼承。
Struct沒有繼承性,不能從另外一個(gè)結(jié)構(gòu)或者類繼承,本身也不能被繼承,雖然結(jié)構(gòu)沒有明確地用sealed聲明,但是結(jié)構(gòu)師隱式的sealed。Struct支持接口繼承。
3.內(nèi)部結(jié)構(gòu):
結(jié)構(gòu)
類
沒有默認(rèn)的(無參數(shù))構(gòu)造函數(shù),但是可以添加構(gòu)造函數(shù),結(jié)構(gòu)可以聲明構(gòu)造函數(shù),但是他們必須是帶參數(shù)的。
有默認(rèn)的構(gòu)造函數(shù)
沒有析構(gòu)函數(shù)
有析構(gòu)函數(shù)
沒有abstract和sealed(因?yàn)椴荒芾^承)
可以使用abstract和sealed
不能有protected修飾符,不可以聲明protected,virtual,sealed和override成員
可以聲明protected,virtual,sealed,override成員
可以不使用new初始化
必須使用new初始化,struct在聲明時(shí)就進(jìn)行了初始化過程,所有的成員變量均默認(rèn)為0或null
在結(jié)構(gòu)中初始化實(shí)例字段是錯(cuò)誤的
Struct變量使用完之后就自動解除內(nèi)存分配
Class實(shí)例有垃圾回收機(jī)制來保證內(nèi)存的回收處理
Struct創(chuàng)建的對象復(fù)制簡單,直接以等號連接即可
Class對象復(fù)制分為淺復(fù)制和深復(fù)制,必須經(jīng)過特別的方法來完成復(fù)制
我們可以簡單地理解為class是一個(gè)可以動的機(jī)器,有行為,有多臺,有繼承,而struct是一個(gè)零件箱,組合了不同結(jié)構(gòu)的零件,其實(shí)class和struct最本質(zhì)的區(qū)別在于class是引用類型,內(nèi)存分配在托管堆,而struct是值類型,內(nèi)存分配在線程堆棧上,此差異導(dǎo)致了上述的所有的不同。
4.如何選擇類和結(jié)構(gòu)
(1)實(shí)現(xiàn)一個(gè)主要勇于存儲數(shù)據(jù)的結(jié)構(gòu)時(shí),可以考慮結(jié)構(gòu)
(2)Struct變量占用堆棧的空間,因此適用于數(shù)據(jù)量相對小的場合,堆棧的空間有限,對于大量的邏輯的對象,創(chuàng)建類要比創(chuàng)建結(jié)構(gòu)好一些。
(3)結(jié)構(gòu)數(shù)組具有更高的效率
(4)結(jié)構(gòu)表示如點(diǎn),矩形和顏色這樣輕量的對象,例如,如果聲明一個(gè)含有1000個(gè)點(diǎn)的對象數(shù)組,則將為引用每個(gè)對象分配附加的內(nèi)存,在此情況下,結(jié)構(gòu)的成本較低。
(5)在表現(xiàn)抽象和多級別的對象層次時(shí),類是最好的選擇
(6)在大多數(shù)情況下,該類型只是一些數(shù)據(jù)時(shí),結(jié)構(gòu)師最佳的選擇。
1.一個(gè)是引用類型一個(gè)是值類型
Class是引用類型,繼承自System.Object類
Struct是值類型,繼承自System.ValueType類,因此不具有多態(tài)性
因?yàn)榻Y(jié)構(gòu)是值類型,所以結(jié)構(gòu)之間賦值可以創(chuàng)建新的結(jié)構(gòu),復(fù)制包含結(jié)構(gòu)的變量時(shí),講復(fù)制所有的數(shù)據(jù),對新的副本所作的修改都不會改變舊副本的數(shù)據(jù),而類是引用類型,類之間的賦值只是復(fù)制引用。
2. 繼承性的區(qū)別
Class支持繼承,可以繼承自類和接口,是完全可擴(kuò)展的,除非聲明sealed。否則類可以繼承自其它的類的接口,自身也能被繼承。
Struct沒有繼承性,不能從另外一個(gè)結(jié)構(gòu)或者類繼承,本身也不能被繼承,雖然結(jié)構(gòu)沒有明確地用sealed聲明,但是結(jié)構(gòu)師隱式的sealed。Struct支持接口繼承。
3.內(nèi)部結(jié)構(gòu):
結(jié)構(gòu)
類
沒有默認(rèn)的(無參數(shù))構(gòu)造函數(shù),但是可以添加構(gòu)造函數(shù),結(jié)構(gòu)可以聲明構(gòu)造函數(shù),但是他們必須是帶參數(shù)的。
有默認(rèn)的構(gòu)造函數(shù)
沒有析構(gòu)函數(shù)
有析構(gòu)函數(shù)
沒有abstract和sealed(因?yàn)椴荒芾^承)
可以使用abstract和sealed
不能有protected修飾符,不可以聲明protected,virtual,sealed和override成員
可以聲明protected,virtual,sealed,override成員
可以不使用new初始化
必須使用new初始化,struct在聲明時(shí)就進(jìn)行了初始化過程,所有的成員變量均默認(rèn)為0或null
在結(jié)構(gòu)中初始化實(shí)例字段是錯(cuò)誤的
Struct變量使用完之后就自動解除內(nèi)存分配
Class實(shí)例有垃圾回收機(jī)制來保證內(nèi)存的回收處理
Struct創(chuàng)建的對象復(fù)制簡單,直接以等號連接即可
Class對象復(fù)制分為淺復(fù)制和深復(fù)制,必須經(jīng)過特別的方法來完成復(fù)制
我們可以簡單地理解為class是一個(gè)可以動的機(jī)器,有行為,有多臺,有繼承,而struct是一個(gè)零件箱,組合了不同結(jié)構(gòu)的零件,其實(shí)class和struct最本質(zhì)的區(qū)別在于class是引用類型,內(nèi)存分配在托管堆,而struct是值類型,內(nèi)存分配在線程堆棧上,此差異導(dǎo)致了上述的所有的不同。
4.如何選擇類和結(jié)構(gòu)
(1)實(shí)現(xiàn)一個(gè)主要勇于存儲數(shù)據(jù)的結(jié)構(gòu)時(shí),可以考慮結(jié)構(gòu)
(2)Struct變量占用堆棧的空間,因此適用于數(shù)據(jù)量相對小的場合,堆棧的空間有限,對于大量的邏輯的對象,創(chuàng)建類要比創(chuàng)建結(jié)構(gòu)好一些。
(3)結(jié)構(gòu)數(shù)組具有更高的效率
(4)結(jié)構(gòu)表示如點(diǎn),矩形和顏色這樣輕量的對象,例如,如果聲明一個(gè)含有1000個(gè)點(diǎn)的對象數(shù)組,則將為引用每個(gè)對象分配附加的內(nèi)存,在此情況下,結(jié)構(gòu)的成本較低。
(5)在表現(xiàn)抽象和多級別的對象層次時(shí),類是最好的選擇
(6)在大多數(shù)情況下,該類型只是一些數(shù)據(jù)時(shí),結(jié)構(gòu)師最佳的選擇。
相關(guān)文章
C#中Clone一個(gè)對象的值到另一個(gè)對象案例
這篇文章主要介紹了C#中Clone一個(gè)對象的值到另一個(gè)對象案例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12C# Winform實(shí)現(xiàn)自定義漂亮的通知效果
這篇文章主要介紹了C# Winform實(shí)現(xiàn)自定義漂亮的通知效果,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08C#?PictureBox控件方法參數(shù)及圖片刪除重命名上傳詳解
這篇文章主要為大家介紹了C#?PictureBox控件方法參數(shù)及圖片刪除重命名上傳示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08C#實(shí)現(xiàn)封裝常用Redis工具類的示例代碼
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)封裝常用Redis工具類的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03vscode設(shè)置Fira_Code字體及改變編輯器字體、背景顏色的代碼詳解
這篇文章主要介紹了vscode設(shè)置Fira_Code字體及改變編輯器字體、背景顏色,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08C#實(shí)現(xiàn)遠(yuǎn)程關(guān)閉和重啟計(jì)算機(jī)的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)遠(yuǎn)程關(guān)閉和重啟計(jì)算機(jī)的功能,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12總結(jié)C#動態(tài)調(diào)用WCF接口的兩種方法
這篇文章給大家總結(jié)了C#動態(tài)調(diào)用WCF接口的兩種方法,大家可以根據(jù)自己的需求選擇對應(yīng)的方式,下面來一起看看。2016-09-09