C#按值傳遞引用類型&按引用傳遞引用類型

C#值類型和引用類型

與引用類型相對的是值類型。

值類型

當把一個值類型賦給另外一個時,就是對字段成員逐一進行復制,此時在棧上新建了值類型的兩個副本,每一個都可以被獨立操作。

引用類型

和棧中的值類型相比,當對引用類型應用賦值操作符時,我們就是在內存中重定向引用變量的指向。
其中,所有類實例都是引用類型。

按值傳遞引用類型

回顧一下形參和實參

這裏寫圖片描述
在一般傳值調用的機制中只能把實參傳送給形參,而不能把形參的值反向地傳送給實參。因此在函數調用過程中,形參值發生改變,而實參中的值不會變化。而在引用調用的機制當中是將實參引用的地址傳遞給了形參,所以任何發生在形參上的改變實際上也發生在實參變量上。
參考:https://baike.baidu.com/item/形參/7677757?fr=aladdin

按值傳遞引用類型實例

假設有一個Person類,一個方法:void SendAPersonByValue(Person p)

void SendAPersonByValue(Person p){
  //改變"p"的年齡
  p.personAge = 99;
  //調用者能看到這個重新賦值嗎?
  p = new Person("Nikki",99);
}

假設在Main()函數中,調用函數的代碼如下:

Person fred = new Person("Fred",12);
SendAPersonByValue(fred);

結果顯示,fred傳進函數中後,他的personAge被改成了99(p.personAge = 99)
但是函數中的 p = new Person(“Nikki”,99);並未起作用。

結果解釋

值傳遞方式下,形參是複製於實參的。
如果傳入的是值類型,那很簡單,就和預期一樣,形參和實參完全沒有關係。
而如果傳入的是引用類型,那麼會複製指向調用者對象的引用。
即p是一個引用變量,複製於傳進來的fred變量,都指向了內存中的同一處,通過p改變該內存的值,fred引用也會看到變化,但是如果通過p 新建一份的內存區,那就和fred指向的內存區沒有什麼關係了。

按引用傳遞引用類型

如果把之前的函數改寫成按引用傳遞引用類型,其形式如下:(C#語言)

void SendAPersonByValue(ref Person p){
  //改變"p"的年齡
  p.personAge = 99;
  //fred引用變量也會受到影響,p和fred指向了堆上的一個新對象
  p = new Person("Nikki",99);
}

此時,Main()函數中的fred引用變量也會受到影響

參考書籍:《精通C#(第六版)Andrew Troelsen》章節4.5

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章