C# 在參考型別做為參數時的一個細節

來源:互聯網
上載者:User

 請先來看一個MSDN協助的樣本,這個樣本是為了說明結構類型與參考型別之間的差異的

class TheClass<br />{<br /> public string willIChange;<br />}</p><p>struct TheStruct<br />{<br /> public string willIChange;<br />}</p><p>class TestClassAndStruct<br />{<br /> static void ClassTaker(TheClass c)<br /> {<br /> c.willIChange = "Changed";<br /> }</p><p> static void StructTaker(TheStruct s)<br /> {<br /> s.willIChange = "Changed";<br /> }</p><p> static void Main()<br /> {<br /> TheClass testClass = new TheClass();<br /> TheStruct testStruct = new TheStruct();</p><p> testClass.willIChange = "Not Changed";<br /> testStruct.willIChange = "Not Changed";</p><p> ClassTaker(testClass);<br /> StructTaker(testStruct);</p><p> System.Console.WriteLine("Class field = {0}", testClass.willIChange);<br /> System.Console.WriteLine("Struct field = {0}", testStruct.willIChange);<br /> }<br />}<br />//輸出:<br />//Class field = "Changed"<br />//Struct field = "Not Changed"

這個例子清楚的說明了,向方法傳入參考型別與結構類型之間的重要差異,如果傳的是參考型別

那麼改變會發生而結構類型不會因為結構類型中改變只是在其等值副本身上發生..

 

下面修改這段代碼,讓引用對象在傳入之前僅申明但不執行個體化.代碼如下:

 class TheClass {<br /> public string willIChange;<br /> public TheClass() {<br /> this.willIChange="Not Changed";<br /> }<br />}</p><p>struct TheStruct {<br /> public string willIChange;<br />}</p><p>class TestClassAndStruct {<br /> static void ClassTaker( ref TheClass c ) { //A處<br /> if (c == null)<br /> c = new TheClass();<br /> c.willIChange = "Changed";<br /> }</p><p> static void StructTaker( TheStruct s ) { //B處<br /> s.willIChange = "Changed";<br /> }</p><p> static void Main() {<br /> TheClass testClass = default(TheClass); //C處<br /> TheStruct testStruct = default(TheStruct);</p><p> //testClass.willIChange = "Not Changed";<br /> testStruct.willIChange = "Not Changed";</p><p> ClassTaker(ref testClass);//D處<br /> StructTaker(testStruct);</p><p> System.Console.WriteLine("Class field = {0}", testClass.willIChange);<br /> System.Console.WriteLine("Struct field = {0}", testStruct.willIChange);<br /> }<br />}

 

這段修改後的代碼結果與先前給出的MSDN範例程式碼的執行結果是一至的, 主要修改了4個地方

A處在類中 改變測試方法的參數修飾加入了ref 關鍵字,B處 增加了建構函式,這個並不關鍵區段

主要是為了替代測試中 賦值的那一行的,C處,是把原來的new 改成了default(T);這樣表示這個

執行個體並沒在傳入方法之前就被構造出來而僅是一個申明,按我的理解申明本就應該是個引用. D處

向參考型別執行個體的測試方法中引用方式的傳入的執行個體,出來的結果是和先前一樣的,但是 我要說的

重點是 如果這個測試方法沒有改變仍然向先前那樣沒有ref的話,那麼 結果就會出錯..

因為沒有ref時 測試的參考型別 TheClass 是在測試方法中new  (構造)出來的,而本來按我的

理解TheClass tc;這樣的單純申明本身就應該是一個引用但為什麼在方法內部對其構造後對它本

身沒有影響呢? 這算是一個值得關注的C#的規則吧,一個很細節的地方.

---

我猜可能是這樣的 引用本身是一個結構 只是這個結構裡面放的是一個記憶體位址,所以
當你傳引用時它仍然是按副本方式傳遞的,而 為什麼 會表現為 被通過方法做了修改呢?,是的,這種

修改其實只是發生在 同 一個地址所指向的那塊記憶體位址裡所在的儲存空間,而只要它們的地址一至

就能夠保證這種訪問的一至性.

結論引用本身就是一個 儲存記憶體位址值的一個結構.一般來說就是 IntPtr結構.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.