傳遞參考類型的參數 (C# 程式設計手冊)Passing Reference-Type Parameters (C# Programming Guide)

參考型別的變數不會直接包含其資料;它會包含其資料的參考。A variable of a reference type does not contain its data directly; it contains a reference to its data. 以值的方式傳遞參考型別參數時,可以變更屬於參考資料的資料,例如類別成員的值。When you pass a reference-type parameter by value, it is possible to change the data belonging to the referenced object, such as the value of a class member. 但您無法變更參考本身的值;例如,您無法使用相同的參考,為新的類別配置記憶體,並讓其保存在方法之外。However, you cannot change the value of the reference itself; for example, you cannot use the same reference to allocate memory for a new class and have it persist outside the method. 若要這樣做,請使用 refout 關鍵字來傳遞參數。To do that, pass the parameter using the ref or out keyword. 為求簡化,下列範例使用 refFor simplicity, the following examples use ref.

以傳值方式傳遞參考型別Passing Reference Types by Value

下列範例示範以傳值方式將 arr 參考型別參數傳遞至 Change 方法。The following example demonstrates passing a reference-type parameter, arr, by value, to a method, Change. 因為參數是對 arr 的參考,所以可以變更陣列元素的值。Because the parameter is a reference to arr, it is possible to change the values of the array elements. 不過,嘗試將參數重新指派至不同的記憶體位置只能在方法內運作,而且不會影響原始的 arr 變數。However, the attempt to reassign the parameter to a different memory location only works inside the method and does not affect the original variable, 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]);
    }
}
/* Output:
    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 參數。In the preceding example, the array, arr, which is a reference type, is passed to the method without the ref parameter. 在這種情況下,指向 arr 的參考複本會傳遞至方法。In such a case, a copy of the reference, which points to arr, is passed to the method. 輸出顯示方法可以變更陣列元素的內容,在此情況下為 1888The output shows that it is possible for the method to change the contents of an array element, in this case from 1 to 888. 不過,在 Change 方法內部使用 new 運算子來配置新的記憶體部分,會讓 pArray 參數參考新的陣列。However, allocating a new portion of memory by using the new operator inside the Change method makes the variable pArray reference a new array. 因此,之後的任何變更將不會影響在 Main 內部建立的 arr 原始陣列。Thus, any changes after that will not affect the original array, arr, which is created inside Main. 事實上,在此範例中會建立兩個陣列,一個在 Main 內部,另一個在 Change 方法內部。In fact, two arrays are created in this example, one inside Main and one inside the Change method.

以傳址式傳遞參考型別Passing Reference Types by Reference

下列範例與上述範例相同,差別在於 ref 關鍵字會新增方法標題和呼叫。The following example is the same as the previous example, except that the ref keyword is added to the method header and call. 任何在方法中進行的變更會影響呼叫端程式中的原始變數。Any changes that take place in the method affect the original variable in the calling program.

class PassingRefByRef 
{
    static void Change(ref int[] pArray)
    {
        // Both of the following changes will affect the original variables:
        pArray[0] = 888;
        pArray = new int[5] {-3, -1, -2, -3, -4};
        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(ref arr);
        System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
    }
}
/* Output:
    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: -3
*/

方法內部進行的所有變更都會影響 Main 中的原始陣列。All of the changes that take place inside the method affect the original array in Main. 事實上,原始陣列會使用 new 運算子重新配置。In fact, the original array is reallocated using the new operator. 因此,在呼叫 Change 方法之後,所有對 arr 的參考都會指向在 Change 方法中建立的五個項目陣列。Thus, after calling the Change method, any reference to arr points to the five-element array, which is created in the Change method.

交換兩個字串Swapping Two Strings

以傳址方式傳遞參考型別參數的絶佳範例就是交換字串。Swapping strings is a good example of passing reference-type parameters by reference. 在此範例中,str1str2 兩個字串會在 Main 中初始化,並作為 ref 關鍵字修改的參數傳遞給 SwapStrings 方法。In the example, two strings, str1 and str2, are initialized in Main and passed to the SwapStrings method as parameters modified by the ref keyword. 兩個字串也會在方法和 Main 內部交換。The two strings are swapped inside the method and inside Main as well.

 class SwappingStrings
 {
     static void SwapStrings(ref string s1, ref string s2)
     // The string parameter is passed by reference.
     // Any changes on parameters will affect the original variables.
     {
         string temp = s1;
         s1 = s2;
         s2 = temp;
         System.Console.WriteLine("Inside the method: {0} {1}", s1, s2);
     }

     static void Main()
     {
         string str1 = "John";
         string str2 = "Smith";
         System.Console.WriteLine("Inside Main, before swapping: {0} {1}", str1, str2);

         SwapStrings(ref str1, ref str2);   // Passing strings by reference
         System.Console.WriteLine("Inside Main, after swapping: {0} {1}", str1, str2);
     }
 }
 /* Output:
     Inside Main, before swapping: John Smith
     Inside the method: Smith John
     Inside Main, after swapping: Smith John
*/

在此範例中,參數需要以傳址方式傳遞以影響呼叫端程式中的變數。In this example, the parameters need to be passed by reference to affect the variables in the calling program. 如果您移除了方法標頭和方法呼叫中的 ref 關鍵字,就不會在呼叫端程式中進行任何變更。If you remove the ref keyword from both the method header and the method call, no changes will take place in the calling program.

如需字串的詳細資訊,請參閱 stringFor more information about strings, see string.

另請參閱See also