最近上連續出現了幾篇關於堆vs棧 值型別vs引用型別的文章。
乙個是關於c# 堆vs棧的,深入淺出,**清晰明了,鏈結如下
c#堆疊對比(part one)
c#堆疊對比(part two)
c#堆疊對比(part three)
c#堆疊對比(part four)
the truth about value types
你真的了解c#中的值和引用嗎?(上)
匹夫細說c#:不是「棧型別」的值型別,從生命週期聊儲存位置
下面是我的思考和總結,希望能與大家分享和討論。
最近和同事一起面試時也經常問這個問題,被面的同學很多回答為「值型別儲存在棧裡,引用型別儲存在堆裡」,首先我們先不去深究這個說法是否準確(上面的文章裡已經說的很清楚)。
值型別和引用型別的區別是儲存位置的不同嗎?
eric lippert給出的答案----值型別和引用型別的區別在語義層面,與儲存位置無關。儲存位置是c#編譯執行時的分配,是實現細節。
或許c# compiler的未來版本中,值型別也可能不儲存在棧裡;
或者某乙個系統平台中並不存在堆和棧的概念。
結論「值型別和引用型別的區別,與儲存位置無關」。
eric lippert說 -值型別和引用型別的區別在語義層面。要怎麼理解?我們思考的視角應該是c#語言語義和使用上。
結論「值型別傳遞的是值(不同的例項,互不影響),引用型別傳遞的是引用(同乙個例項,互相影響)」
如同一句廢話!那我們試著換幾種方式來描述(可能不準確)
1. 值型別是私有的,是持有者自己的東西;引用型別是共享的,大家共有的東西。
2. 值型別是多例項的,每次傳遞都建立新例項;引用型別是單例項的,每次傳遞都是同乙個例項,如設計模式中的單例。
3. 值型別的生命週期和持有者相同;引用型別的生命週期和持有者不同。(有關生命週期的言論)
如何實現值型別和引用型別的儲存?
有兩種儲存方式可供選擇
一直接儲存的優點是效能高,缺點是共享不方便。(棧或者堆上)
二間接儲存的優點是共享方便,缺點是多了一次跳轉,有效能損失。(堆上)
我們要的關注哪些問題?效能,共享方式(生命週期)
值型別是不共享的,它的生命週期和持有者相同,所以可以直接儲存,如果間接儲存,會多一次跳轉,沒有意義的效能損失。
引用型別是共享的,它的生命週期和持有者不同,所以採用間接儲存,如果直接儲存,是很難實現共享和生命週期的不同。
結論值型別是直接儲存,引用型別是間接儲存。是基於實現的考量,不是值型別和引用型別的區別。
生命週期是從實現角度思考的推論,也不是值型別和引用型別的區別。
思考後發現,所有值型別都可以被引用型別所替代,那為什麼要有值型別呢?沒有得出理想的答案,推測有兩種可能
一 歷史傳承。
二 基於效能的考量。這個應該是實現級別的事情,為什麼被暴露在語言級別上?沒有辦法解決嗎?(對於值來說,引用型別多了一次跳轉;對於引用來說,值的傳遞多了一次深轉殖)
在工作中很少(幾乎沒有)使用struct,因為效能上的收益遠遠無法彌補維護成本的損失。
(不能要求每個開發人員都很了解struct和class的不同,並在修改**時意識到使用的是struct而不是class)
值和引用型別的區別是語言和使用級別的
值型別傳遞的是值(不同的例項,互不影響),引用型別傳遞的是引用(同乙個例項,互相影響)
有關值型別和引用型別儲存在棧或者堆上的言論,是基於實現細節的思考,是當前的實現方式,不是值型別和引用型別的區別。
有關值型別和引用型別生命週期的言論,是基於實現細節的思考,是當前的實現方式,不是值型別和引用型別的區別。
值型別(struct)更多是效能上的收益,c#中定義的基礎值型別已經足夠,開發中盡量避免定義值型別(struct)。
C 堆與棧 值型別 引用型別
先說c 中值型別和引用型別 概念 1.值型別 資料儲存在記憶體的堆疊中,從堆疊中可以快速地訪問這些資料,因此,值型別表示實際的資料。2.引用型別 表示指向儲存在記憶體堆中的資料的指標或引用 包括類 介面 陣列和字串 c 中定義的值型別包括原型別 sbyte byte short ushort int...
值型別何引用型別,堆和棧
本文主要是討論棧和堆的含義,也就是討論 c 的兩種類據型別 值型別和引用型別 雖然我們在.net中的框架類庫中,大多是引用型別,但是我們程式設計師用得最多的還是值型別。引用型別如 string,object,class等總是在從託管堆上分配的,c 中new操作符返回物件的記憶體位址 也就是指向物件資...
值型別和引用型別,棧和堆的含義
原文出自 本文主要是討論棧和堆的含義,也就是討論 c 的兩種類據型別 值型別和引用型別 雖然我們在.net中的框架類庫中,大多是引用型別,但是我們程式設計師用得最多的還是值型別。引用型別如 string,object,class等總是在從託管堆上分配的,c 中new操作符返回物件的記憶體位址 也就是...