C#中的結構的功能非常強大,可以看做一個微型的類。可以包含構造函數(但有一些限制),常數,字段,方法,屬性,索引器,運算符和嵌套類型等,甚至可以重寫System.Object中的虛方法。
但struct和class還是有一些區別的:
類型:結構是值類型,類是引用類型
存儲位置:結構存儲在堆棧上,類存儲在托管堆上
傳遞值:結構傳遞自身的副本,類傳遞引用的副本
構造函數:結構不能自定義無參的構造函數,而且在構造函數中要給所有的字段成員賦值
析構函數:結構不能自定義析構函數
初始化:結構聲明中除非字段被聲明成const 或 static,否則不能初始化
創建實例:結構在創建實例時可以不用new,而類必須用new
繼承:結構不支持繼承,只能實現接口
訪問修飾符:結構不支持繼承也就不能用protected和protected internal
結構聲明中不允許使用abstract和sealed修飾符(結構不抽象,隱式密封)
一般情況下,我們很少使用結構,而且很多人也並不建議使用結構,但鑒於結構的這些特性和運行機制,合理正確的應用struct可以很好的提高性能,節約資源。
經常使用的類型,而且這些類型以數據為主不需要復雜的操作時聲明成struct
一個類型如果數據量比較大而且會經常修改涉及到一些復雜操作,即使能用struct實現也要聲明成類,因為類可以在以後的升級中更好的進行擴展
提供某些和非托管代碼通信的兼容性
在.NET 框架中,System.Drawing命名空間中的有些元素,如:System.Drawing.Point、System.Guid就是實現為struct,而不是class,其原因也正在於以上介紹的各方面的權衡
一下內容來自互聯,可以更好的幫助我們了解為什麼用結構
博客園“越過林子”
結構是值類型,所以會影響性能,但根據使用結構的方式,這種影響可能是正面的,也可能是負面的。正面的影響是為結構分配內存時,速度非常快,因為它們將內 聯或者保存在堆棧中。在結構超出了作用域被刪除時,速度也很快。另一方面,只要把結構作為參數來傳遞或者把一個結構賦給另一個結構(例如A=B,其中A和B是結構),結構的所有內容就被復制,而對於類,則只復制引用。這樣,就會有性能損失,根據結構的大小,性能損失也不同。注意,結構主要用於小的數據結構。但當把結構作為參數傳遞給方法時,就應把它作為ref參數傳遞,以避免性能損失——此時只傳遞了結構在內存中的地址,這樣傳遞速度就與在類中的傳遞速度一樣快了。另一方面,如果這樣做,就必須注意被調用的方法可以改變結構的值。
博客園“佳園”
為在設計編程語言時將結構設計成無繼承性?
其實類的繼承是有相當的成本的 ——由於繼承性,每個類需要用額外的數據空間來存儲“繼承圖”來表示類的傳承歷史,
通俗地說來就是我們人類的家族家譜,裡面存儲著我們的祖宗十八代,只有這樣我們才知道我們從哪裡來的,而家譜肯定是需要額外的空間來存放的。
大家不要覺得這個存放“繼承圖”的空間很小,如果我們的程序需要用10000個點(Point)來存放游戲中的人物形體數據的話,
在一個場景中又有N個人,這個內存開銷可不是小數目了。所以我們可以通過將點(Point)申明成 Struct而不是class來節約內存空間。