在下面的示例中,初始化字符串数组并将其作为参数传递给字符串的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
答案 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; 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; Main
- 手ChangeArray
便条,上面带有数字1。ChangeArray
- 要求Universe Reverse
数组。 Universe反转数组并告诉ChangeArray
新数组位于插槽2中。ChangeArray
- 横过便利贴上的1并写下2
。在这种情况下,调用者现在具有对反转数组的 new 引用。由于传递了引用(&#34;粘滞便笺&#34;)而不是值(注释中的数字),调用者会看到对该引用的任何更改
现在让我们看一下ChangeArrayElements
:
Main
- 标有&#34;周日&#34; Main
- 告诉ChangeArrayElements
插槽1处有一个数组。ChangeArrayElements
- 在标有arr
的便条上写下数字1。ChangeArrayElements
- 更改插槽1中数组前三个存储区中的值。请注意,这里的区别在于原始数组已被修改。由于调用者和函数都在查看相同的数组,因此它们都会看到更改。