为什么一个数组在没有引用的情况下传递,在方法内部被 CopyTo 更改?
Why is an array passed without ref, changed by CopyTo inside the method?
由于传入的数组参数没有ref关键字,这段代码输出数组的初始值(即1...6):
using System;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var arr = new int[] {1, 2, 3, 4, 5, 6};
Rotate(arr, 3);
Console.WriteLine(string.Join(',', arr));
}
static void Rotate(int[] nums, int k)
{
var tail = nums.TakeLast(k).ToArray();
nums = tail.Concat(nums)
.Take(nums.Length)
.ToArray();
}
}
很明显,因为在 Rotate 方法内部有它自己的数组,其中包含从参数值复制而来的值。如果我想在调用方法中更改 arr 值,我需要通过 ref 将它传递给 Rotate 方法,它可以工作。
但我不明白,为什么如果用 CopyTo() 方法替换赋值,参数的行为就像它通过引用传递一样:
static void Rotate(int[] nums, int k)
{
var tail = nums.TakeLast(k).ToArray();
tail.Concat(nums)
.Take(nums.Length)
.ToArray()
.CopyTo(nums, 0);
}
因为CopyTo()
将元素设置在数组内部,并不会重新分配数组变量本身。
.ToArray()
创建一个新对象,而 CopyTo()
修改它。后者通过对现有数组的引用。
另见 Passing Arrays by Value and by Reference 和许多其他内容。
下面将以图形方式解释发生的情况。您的 3 种方法(常规、CopyTo 和 ref)非常不同..
我已经概述了交换算法的相对复杂性,但大多数情况下您可以忽略它。所有这一切最重要的一点是当您使用 ref
时会发生什么,以及当您操作正在传递的引用类型的 contents 时会发生什么。内容操作与将整个内容换成其他内容非常不同
点击展开..
由于传入的数组参数没有ref关键字,这段代码输出数组的初始值(即1...6):
using System;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var arr = new int[] {1, 2, 3, 4, 5, 6};
Rotate(arr, 3);
Console.WriteLine(string.Join(',', arr));
}
static void Rotate(int[] nums, int k)
{
var tail = nums.TakeLast(k).ToArray();
nums = tail.Concat(nums)
.Take(nums.Length)
.ToArray();
}
}
很明显,因为在 Rotate 方法内部有它自己的数组,其中包含从参数值复制而来的值。如果我想在调用方法中更改 arr 值,我需要通过 ref 将它传递给 Rotate 方法,它可以工作。 但我不明白,为什么如果用 CopyTo() 方法替换赋值,参数的行为就像它通过引用传递一样:
static void Rotate(int[] nums, int k)
{
var tail = nums.TakeLast(k).ToArray();
tail.Concat(nums)
.Take(nums.Length)
.ToArray()
.CopyTo(nums, 0);
}
因为CopyTo()
将元素设置在数组内部,并不会重新分配数组变量本身。
.ToArray()
创建一个新对象,而 CopyTo()
修改它。后者通过对现有数组的引用。
另见 Passing Arrays by Value and by Reference 和许多其他内容。
下面将以图形方式解释发生的情况。您的 3 种方法(常规、CopyTo 和 ref)非常不同..
我已经概述了交换算法的相对复杂性,但大多数情况下您可以忽略它。所有这一切最重要的一点是当您使用 ref
时会发生什么,以及当您操作正在传递的引用类型的 contents 时会发生什么。内容操作与将整个内容换成其他内容非常不同
点击展开..