傳遞參考型別參數(C#)

來源:互聯網
上載者:User
MSDN:

參考型別的變數不直接包含其資料;它包含的是對其資料的引用。當通過值傳遞參考型別的參數時,有可能更改引用所指向的資料,如某類成員的值。但是無法更改引用本身的值;也就是說,不能使用相同的引用為新類分配記憶體並使之在塊外保持。若要這樣做,應使用 ref 或 out 關鍵字傳遞參數。為了簡單起見,下面的樣本使用 ref

下面的樣本示範通過值向 Change 方法傳遞參考型別的參數 arr。由於該參數是對 arr 的引用,所以有可能更改數組元素的值。但是,試圖將參數重新分配到不同的記憶體位置時,該操作僅在方法內有效,並不影響原始變數 arr。

 

class PassingRefByVal 
{
    static void Change(int[] pArray)
    {
        pArray[0] = 888;  // This change affects the original element.
        pArray = new int[5] {-3, -1, -2, -3, -4};   // This change is local.
        System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
    }

    static void Main() 
    {
        int[] arr = {1, 4, 5};
        System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]);

        Change(arr);
        System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]);
    }
}

 

輸出

 Inside Main, before calling the method, the first element is: 1

Inside the method, the first element is: -3

Inside Main, after calling the method, the first element is: 888

 

代碼討論

 在上個樣本中,數組 arr 為參考型別,在未使用 ref 參數的情況下傳遞給方法。在此情況下,將向方法傳遞指向 arr 的引用的一個副本。輸出顯示方法有可能更改數組元素的內容,在這種情況下,從 1 改為 888。但是,在 Change 方法內使用 new 運算子來分配新的記憶體部分,將使變數 pArray 引用新的數組。因此,這之後的任何更改都不會影響原始數組 arr(它是在 Main 內建立的)。實際上,本樣本中建立了兩個數組,一個在 Main 內,一個在 Change 方法內。 以上引用地址:http://msdn.microsoft.com/zh-cn/library/s6938f28(v=VS.80).aspx 

另,樣本:

 

protected void Button1_Click(object sender, EventArgs e)
    {
        Class1 obj1 = new Class1();
        obj1.Name = "name1";
        obj1.ID = "1";

        Class1 obj2 = GetObj(obj1);

        Response.Write("obj1 => ID:"+obj1.ID+";Name:"+obj1.Name);
        Response.Write("<br/>");
        Response.Write("obj2 => ID:" + obj2.ID + ";Name:" + obj2.Name);
    }

    protected Class1 GetObj(Class1 c)
    {
        c.ID = "3";

        Class1 b = new Class1();
        b.ID = "2";
        b.Name = "name2";
        c = b;

        return c;
    }

 

 輸出結果:

 

obj1 => ID:3;Name:name1
obj2 => ID:2;Name:name2

 

個人理解:

 

對象作為參數傳遞時,傳遞的是對象的引用(即:使用地址)。比如原來對象(obj1)在地址22處,那麼在GetObj方法內,首先對c進行修改,那麼修改的也是地址22處的對象,即obj1對象。當執行語句c=b;時,那麼原本指向22地址的指標被賦予了新的地址,比如33,那麼再對c進行各種操作,那麼操作的目標也只能是地址33處的新對象,與地址為22處的對象obj1再也不發生任何關係了。因此也就出現了以上結果。

由此擴充並推斷出:在方法參數傳遞時,不加out、ref的情況下,c#都是按值傳遞參數的。對於實值型別的參數,拷貝的是值本身。對於引用型對象,也進行拷貝,只不過是拷貝了該對象的指標!

在加out、ref情況下,一旦方法內部有new之類記憶體重新分配語句,系統將對原對象進行重新分配,即將原對象指標將指向新對象地址!

 

理解不當之處,敬請指出。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.