值型別與引用型別(中

2021-09-23 21:23:17 字數 2959 閱讀 7208

本文將介紹以下內容:

1. 引言

上回[第八回:品味型別---值型別與引用型別(上)-記憶體有理

]的發布,受到大家的不少關注,我們從記憶體的角度了解了值型別和引用型別的所以然,留下的任務當然是如何應用型別的不同特點在系統設計、效能優化等方面發揮其作用。因此,本回是對上回有力的補充,同時應朋友的希望,我們盡力從記憶體除錯的角度來著眼一些設計的分析,這樣就有助於對這一主題進行透徹和全面的理解,當然這也是下一回的重點。

2. 通用規則與比較

通用有規則:

簡單的說是由於string的immutable特性,因此每次對string的改變都會在託管堆中產生乙個新的string變數,上述string作為引數傳遞時,實際上執行了s=s操作,在託管堆中會產生乙個新的空間,並執行資料拷貝,所以才有了類似於按值傳遞的結果。但是根據我們的記憶體分析可知,string在本質上還是乙個引用型別,在引數傳遞時發生的還是按址傳遞,不過由於其特殊的恆定特性,在函式內部新建了乙個string物件並完成初始化,但是函式外部取不到這個變化的結果,因此對外表現的特性就類似於按值傳遞。至於string型別的特殊性解釋,我推薦artech

的大作《深入理解string和如何高效地使用string

》。另外,string型別過載了==操作符,在型別比較是比較的是實際的字串,而不是引用位址,因此有以下的執行結果:

string astring = "123";

string bstring = "123";

console.writeline((astring == bstring)); 

//顯示為true,等價於astring.equals(bstring);

string cstring = bstring;

cstring = "456";

console.writeline((bstring == cstring)); 

//顯示為false,等價於bstring.equals(cstring);

public

struct mystructtester

public

class isvaluetype_test

belongs to value type.", astruct.tostring()); }

} }

mystruct atest;

console.writeline(atest.x); 

char a = 'c';

char b = 'c';

console.writeline((a.equals(b))); 

//會返回true; 

比較出真知:

3. 對症下藥-應用場合與注意事項

現在,在記憶體機制了解和通用規則熟悉的基礎上,我們就可以很好的總結出值型別和引用型別在系統設計時,如何作出選擇?當然我們的重點是告訴你,如何去選擇使用值型別,因為引用型別才是.net的主體,不必花太多的關照就可以贏得市場。

3.1 值型別的應用場合

3.2 引用型別的應用場合

4. 再論型別判等

型別的比較通常有equals()、referenceequals()和==/!=三種常見的方法,其中核心的方法是equals。我們知道equals是system.object提供的虛方法,用於比較兩個物件是否指向相同的引用位址,.net framework的很多態別都實現了對equals方法的重寫,例如值型別的「始祖」system.valuetype就過載了equal方法,以實現對例項資料的判等。因此,型別的判等也要從重寫或者過載equals等不同的情況具體分析,對值型別和引用型別判等,這三個方法各有區別,應多加注意。

4.1 值型別判等

4.2 引用型別判等

public

virtual

bool equals(

object obj);

public

static

bool equals(

object obja, 

object objb);

一種是虛方法,預設為引用位址比較;而靜態方法,如果obja是與objb相同的例項,或者如果兩者均為空引用,或者如果obja.equals(objb)返回true,則為true;否則為false。.net的大部分類都重寫了equals方法,因此判等的返回值要根據具體的重寫情況決定。 

有必要在自定義的型別中,實現對equals和==的重寫或者過載,以提高效能和針對性分析。 

5. 再論型別轉換

型別轉換是引起系統異常乙個重要的因素之一,因此在有必要在這個主題裡做以簡單的總結,我們不力求照顧全面,但是追去提綱挈領。常見的型別轉換包括:

(type)(變數、表示式)

static 訪問修飾操作符 轉換修飾操作符 

operator 型別(引數列表);

public student

//其中,所有的轉換都必須是static的。  

6.結論

現在,我們從幾個角度延伸了上回對值型別和引用型別的分析,正如本文開頭所言,對型別的把握還有很多可以挖掘的要點,但是以偏求全的辦法我認為還是可取的,尤其是在技術探求的過程中,力求面面俱到的做法並不是好事。以上的幾個角度,我認為是對值型別和引用型別把握的必經之路,否則在實際的系統開發中常常會在細小的地方栽跟頭,摸不著頭腦。

品味型別,我們以應用為要點撬開值型別和引用型別的規矩與方圓。

品味型別,我們將以示例為導航,開動乙個層面的深入分析,下回《第十回:品味型別---值型別與引用型別(下)-應用征途》我們再見。 

值型別與引用型別

直白點兒說 值型別就是現金,要用直接用 引用型別是存摺,要用還得先去銀行取現。麥機長 我覺得這話十分形象。宣告乙個值型別變數,編譯器會在棧上分配乙個空間,這個空間對應著該值型別變數,空間裡儲存的就是該變數的值。引用型別的例項分配在堆上,新建乙個引用型別例項,得到的變數值對應的是該例項的記憶體分配位址...

值型別與引用型別

工作許久了,可是對c 中的值型別和引用型別卻一直無法很好的理解。這兩天花了不少時間查詢資料,看文章,終於有所收穫,在此將自己理解整理出來,方便日後自己檢視,同時希望對跟我有一樣困惑的朋友有所幫助。廢話不多說,下面開始說說怎麼理解值型別和引用型別!值型別資料直接在他自身分配到的記憶體中儲存資料,而引用...

值型別與引用型別

自動變數型別是指儲存於該程式 程序 堆疊空間的一種變數型別 注意此時的堆疊空間並不是組合語言上的堆疊,只是它的使用及釋放類似於堆疊的過程 這個變數型別的乙個特點是它在程式執行時存在,在程式結束時消失。正是這個過程類似於彙編裡棧的操作,所以才將其命名 處理 為堆疊。我們平時所定義的int之類的型別都屬...