1. 程式人生 > >c#中Class和Struct使用與性能的區別

c#中Class和Struct使用與性能的區別

回收 數據結構 com 垃圾回收 父類 改變 med .cn 指針

在Unity中很多已經定義為結構體的數據結構
  • Vector2, Vector3 和 Vector4
  • Rect
  • Color和Color32
  • Bounds
  • Touch

1.Class為引用類型,Struct為值類型

值類型與引用類型的區別這兩篇文章講得很好 http://www.cnblogs.com/tonney/archive/2011/04/28/2032205.html http://blog.csdn.net/liulong1567/article/details/50678930 雖然我們在.net中的框架類庫中,大多是引用類型,但是我們程序員用得最多的還是值類型。

引用類型如:string,Object,class等總是在從托管堆

上分配的,C#中new操作符返回對象的內存地址--也就是指向對象數據的內存地址。

以下是值類型與引用類型的表: 技術分享技術分享 從這張圖可以看出,class(類)實例化出來的對象,指向了內存堆中分配的空間 struct(結構)實例化出來的對象,是在內存棧中分配 所以,值類型和引用類型的區別就是: 1、它們存儲的位置不一樣 2、如果是引用類型,當兩個對象指向同一個地方,修改某一個的時候,其它對象的值會發生改變 當說到類的實例是傳引用時,實際過程是,先獲取一個指針,它指向對象在內存中的地址,然後傳遞這個指針。這很重要,因為一個類的實例,實際上可能很大,包含了很多域甚至其他對象。在這種情況下,賦值和傳遞整個實例可能非常影響性能,這就為什麽要用傳地址來替代。
說到傳值時,實際過程是,對這個變量進行全克隆/拷貝,然後傳遞這個副本,原始值不變。結構體就是值類型,它是傳值的。這意味著,結構體是理想的小型數據結構。 由於引用類型在托管堆上分配,它只會在調用垃圾回收時才被清理。 值類型實在內存棧上分配,這就說明他們很容易被回收,而且不受垃圾回收的影響。 數據類型分隔為值類型和引用類型。值類型要麽是堆棧分配的,要麽是在結構中以內聯方式分配的。引用類型是堆分配的。引用類型和值類型都是從最終的基類 Object 派生出來的。當值類型需要充當對象時,就在堆上分配一個包裝(該包裝能使值類型看上去像引用對象一樣),並且將該值類型的值復制給它。該包裝被加上標記,以便系統知道它包含一個值類型。這個進程稱為裝箱,其反向進程稱為取消裝箱。裝箱和取消裝箱能夠使任何類型像對象一樣進行處理。

2.Class可以繼承父類,Struct不可以

所有結構體都默認繼承System.ValueType父類,所以不能繼承別的父類,ValueType是值類型的基類,詳見:https://msdn.microsoft.com/zh-cn/library/system.valuetype(VS.80).aspx

3.Struct必須在構造函數對所有變量賦值

結構體中所有變量都必須在構造函數中初始化

4.Struct沒有默認構造函數

Struct不允許有參數為空的構造函數

5.Struct與class的性能上的優缺點

關於值類型與引用類型的內存可以看這篇文章:https://msdn.microsoft.com/zh-cn/dd365372 值類型的實例化之後在內存的大小就是其所有內容物大小,也就是內容物內存越大、占用內存越大,存放在棧中,但是取值更快,不需要GC回收 引用類型把值存放在堆中,引用存在棧中,實例化時要在堆中取值,所以更消耗時間,但是更省內存,因為只用引用指針的大小,需要GC回收
值類型 引用類型
內存
耗時
GC

6.Struct類型變量默認不可為空

也就是說,不能寫這個語句 struct != null,如果像這樣做的話,一定要加上?,為它取值要加上Value,判斷是否為空要用HasValue Struct? struct = *****; if(struct.HasValue) struct.Value.***** = ****; 原因參考這篇文章:http://blog.csdn.net/xiaojie_cp/article/details/45892325 值類型後面加問號表示可為空null(Nullable 結構) Nullable是.NET 2.0中新提供的一種用於標明一個值類型是否可以為空的技術。 對於一個類型,如果既可以給它分配一個值,也可以給它分配空引用null(表示沒有任何值),我們就說這個類型是可空的。 因此,可空類型可表示一個值,或表示不存在任何值。例如,類似 String 的引用類型就是可空類型,而類似 Int32 的值類型不是可空類型。Nullable 結構支持將值類型擴展為可以為null,但不支持在引用類型上使用,因為引用類型本身就是可空的。 因為值類型的容量只夠表示適合於該類型的值,因此它不可為空;值類型沒有表示空值所需的額外容量。 例:public int? age;

等同 Nullable<int>

7.其他

值類型還有一個特性就是一旦修改值,就會產生一個值類型的副本 引用類型修改值,不會產生副本,但所有有該引用的值都會被修改


by wolf96 2017/7/19

c#中Class和Struct使用與性能的區別