将数组作为参数传递

时间:2014-09-16 13:00:51

标签: c# arrays arguments

在下面的示例中,初始化字符串数组并将其作为参数传递给字符串的PrintArray方法。该方法显示数组的元素。接下来,调用方法ChangeArray和ChangeArrayElement来演示按值发送数组参数不会阻止更改数组元素。 我的问题是数组如何在方法changeArray中没有改变..但是在方法ChangeArrayElements中改变了? 这是一个例子:

class ArrayClass
{
    static void PrintArray(string[] arr)
    {
        for (int i = 0; i < arr.Length; i++)
        {
            System.Console.Write(arr[i] + "{0}", i < arr.Length - 1 ? " " : "");
        }
        System.Console.WriteLine();
    }

    static void ChangeArray(string[] arr)
    {
        // The following attempt to reverse the array does not persist when 
        // the method returns, because arr is a value parameter.
        arr = (arr.Reverse()).ToArray();
        // The following statement displays Sat as the first element in the array.
        System.Console.WriteLine("arr[0] is {0} in ChangeArray.", arr[0]);
    }

     static void ChangeArrayElements(string[] arr)
    {
        // The following assignments change the value of individual array  
        // elements. 
        arr[0] = "Sat";
        arr[1] = "Fri";
        arr[2] = "Thu";
        // The following statement again displays Sat as the first element 
        // in the array arr, inside the called method.
        System.Console.WriteLine("arr[0] is {0} in ChangeArrayElements.", arr[0]);
    }

    static void Main()
    {
        // Declare and initialize an array. 
        string[] weekDays = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

        // Pass the array as an argument to PrintArray.
        PrintArray(weekDays);

        // ChangeArray tries to change the array by assigning something new 
        // to the array in the method. 
        ChangeArray(weekDays);

        // Print the array again, to verify that it has not been changed.
        System.Console.WriteLine("Array weekDays after the call to ChangeArray:");
        PrintArray(weekDays);
        System.Console.WriteLine();

        // ChangeArrayElements assigns new values to individual array 
        // elements.
        ChangeArrayElements(weekDays);

        // The changes to individual elements persist after the method returns. 
        // Print the array, to verify that it has been changed.
        System.Console.WriteLine("Array weekDays after the call to      ChangeArrayElements:");
        PrintArray(weekDays);
    } 
}
// Output:  
// Sun Mon Tue Wed Thu Fri Sat 
// arr[0] is Sat in ChangeArray. 
// Array weekDays after the call to ChangeArray: 
// Sun Mon Tue Wed Thu Fri Sat 
//  
// arr[0] is Sat in ChangeArrayElements. 
// Array weekDays after the call to ChangeArrayElements: 
// Sat Fri Thu Wed Thu Fri Sat

1 个答案:

答案 0 :(得分:2)

在这种方法中:

static void ChangeArray(string[] arr)
{
    // The following attempt to reverse the array does not persist when 
    // the method returns, because arr is a value parameter.
    arr = (arr.Reverse()).ToArray();
    // The following statement displays Sat as the first element in the array.
    System.Console.WriteLine("arr[0] is {0} in ChangeArray.", arr[0]);
}

您没有更改源数组 - 您正在创建 new 数组并将引用保存在同一个变量中。

由于arr中的引用是按值传递的,因此调用方仍然具有对原始数组的引用 - 事实上您有 new 引用反转数组不会改变调用者的引用。

通过合同,在ChangeArrayElements中您正在更改传入的数组,因此调用者可以看到这些更改。

如果数组引用是通过引用传递的

static void ChangeArray(ref string[] arr)
{
    // Since 'arr' is passed by reference, changing the value of 'arr'
    // changes the reference that the caller has.
    arr = (arr.Reverse()).ToArray();
    // The following statement displays Sat as the first element in the array.
    System.Console.WriteLine("arr[0] is {0} in ChangeArray.", arr[0]);
}

然后调用者会看到更改,因为您将更改调用者持有的引用。

这是一个故事(希望如此),说明了不同之处:

按值传递引用类型:

  • Main - 向宇宙询问一个数组 - 宇宙告诉它&#34;数组在插槽1&#34;中。
  • Main - 在标有&#34; weekDays&#34;
  • 的便利贴上写1
  • Main - 告诉ChangeArray插槽1处有一个数组。
  • ChangeArray - 在标有arr的便条上写下数字1。
  • ChangeArray - 要求Universe Reverse数组。 Universe反转数组并告诉ChangeArray新数组位于插槽2中。
  • ChangeArray - 将标有arr的便条上的1翻译过来并写下2

如您所见,由于Reverse不会更改原始数组,因此调用者引用的数组不会更改。

通过引用传递引用类型:

  • Main - 向宇宙询问一个数组 - 宇宙告诉它&#34;数组在插槽1&#34;中。
  • Main - 在标有&#34; weekDays&#34;
  • 的便利贴上写1
  • Main - 手ChangeArray 便条,上面带有数字1。
  • ChangeArray - 要求Universe Reverse数组。 Universe反转数组并告诉ChangeArray新数组位于插槽2中。
  • ChangeArray - 横过便利贴上的1并写下2

在这种情况下,调用者现在具有对反转数组的 new 引用。由于传递了引用(&#34;粘滞便笺&#34;)而不是(注释中的数字),调用者会看到对该引用的任何更改

现在让我们看一下ChangeArrayElements

  • Main - 标有&#34;周日&#34;
  • 的便利贴上仍有1张
  • Main - 告诉ChangeArrayElements插槽1处有一个数组。
  • ChangeArrayElements - 在标有arr的便条上写下数字1。
  • ChangeArrayElements - 更改插槽1中数组前三个存储区中的值。

请注意,这里的区别在于原始数组已被修改。由于调用者和函数都在查看相同的数组,因此它们都会看到更改。