C# - 值类型、引用类型走出误区,容易错误的说法
?
1. 值類型與引用類型小總結
1)對于引用類型的表達式(如一個變量),它的值是一個引用,而非對象。
2)引用就像URL,是允許你訪問真實信息的一小片數據。
3)對于值類型的表達式,它的值是實際的數據。
4)有時,值類型比引用類型更有效,有時恰好相反。
5)引用類型的對象總是在堆上,值類型的值既可能在棧上,也可能在堆上,具體取決于上下文。
6)引用類型作為方法參數使用時,參數默認是以‘值傳遞’方式來傳遞的,但值本身是一個引用。
7)值類型的值會在需要引用類型的行為時裝箱;拆箱則是相反的過程。
?
2. 誤區一 結構是輕量級的類
這個誤解存在著多種形式。有人認為值類型不能或不應有方法或有其他意義的行為:它們應作為簡單的數據轉移類型來使用,只應該有public字段或簡單的屬性。對于這種說法,一個非常典型的反例就是Datetime類型。DateTime作為值類型來提供是很有道理的,因為它非常適合作為和數字或字符相似的一個基本單位來使用。另外,它也理應被賦予對它的值執行計算的能力。換個角度來看這個問題,是數據轉移類型一般都是引用類型??傊?#xff0c;具體應該如何決定,應取決于需要的是值類型的語義,還是引用類型的語義,而不是取決于這個簡單類型與否。
還有一些人認為值類型之所以顯得比引用類型‘輕’,是因為性能,事實是在某些情況下,值類型很能‘干’:它們不需要垃圾回收,(除非被裝箱)不會因類型標識而產生開銷,也不需要解引用。但在其他方面,引用類型顯得更‘能干’:在傳遞參數、賦值、將值返回和執行類似的操作時,只需復制4或8字節(需要看運行的是32位或是64位CLR),而不是復制全部數據。假定ArrayList是一個所謂‘純的’值類型,那么將一個ArrayList表達式傳給一個方法時,就得復制它的所有數據!幾乎在所有情況下,性能問題都不是根據這種判斷來決定的。瓶頸從來都不是想當然的,在你根據性能進行設計之前,需要衡量不同的選擇。
值得注意的是,將這兩者相結合也不能解決問題:類型(不管是類還是結構)擁有多少方法并不重要,每個實例所占用的內存不會受到影響。(代碼本身會消耗內存,但這只會發生一次,而不是每個實例都發生)
?
3. 誤區二 引用類型保存在堆上,值類型保存在棧上
這個誤區主要應歸咎于轉述這句話的人根本沒有動腦筋。這一部分是正確的,引用類型的實例總是在堆上創建的。但第二部分就有問題了。
前面講述過,變量的值是在它聲明的位置存儲的。所以,假定一個類中又一個int類型的實例變量,那么在這個類中的任何對象中,該變量的值總是和對象中的其他數據在一次,也就是在堆上。只有局部變量(方法內部聲明的變量)和方法參數在棧上。對于C#2或以上版本,很多局部變量并不完全存放在棧中。
?
4. 誤區三 對象在C#中默認是通過引用傳遞的
這或許是傳播得最廣的一個誤區了。統一說這句話的人一般知道C#實際的行為是什么,但不知道‘引用傳遞pass by reference’的真正意思是什么??上?#xff0c;那些真正知道引用傳遞是什么意思的人,在聽到這句話時會被完全搞糊涂。
‘引用傳遞’的正式定義相當復雜,要涉及坐值(1-values)和類似的計算機科學術語。但最重要的一點是,假如以引用傳遞的方式來傳送一個變量,那么調用的方法可以通過更改其參數值,來改變調用者的變量值?,F在請記住,引用類型變量的值是引用,而不是對象本身。不需要按引用來傳遞參數本身,就可以更改該參數的引用的那個對象的內容。例如,下面的方法更改了相關對象StringBuilder的內容,但調用者的表達式引用的仍然是之前的那個對象:
public void AppendHello(StringBuilder builder){builder.Append("Hello");}調用這個方法時,參數值(對StringBuilder的一個引用)是以值傳遞pass by value 的方式傳遞的。如果想在方法內部更改builder變量的值,如執行builder=null 語句,調用者看不見這個改變,剛好跟錯誤認識相反。
有趣的是,這種錯誤說法中,不僅引用傳遞的說法有誤,而且 對象傳遞的說法也存在問題。無論引用傳遞還是值傳遞,永遠不會傳遞對象本身。涉及一個引用類型時,要么以引用傳遞的方式傳遞變量,要么以傳值的方式傳遞參數值(引用)。最起碼,這回答了‘當null作為一個傳值參數的值來使用時會發生什么’的問題。假如傳遞的是對象,這是就會出問題,因為沒有一個對象可供傳遞!相反,null引用會采用和其他引用一樣的值傳遞方式傳遞。
?
可以關注本人的公眾號,多年經驗的原創文章共享給大家。
posted on 2017-01-06 16:45 alun-chen 閱讀(...) 評論(...) 編輯 收藏轉載于:https://www.cnblogs.com/alunchen/p/6256903.html
總結
以上是生活随笔為你收集整理的C# - 值类型、引用类型走出误区,容易错误的说法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jenkins创建Maven项目及SSH
- 下一篇: 2017-01-09