0

由于数组参数是在没有引用关键字的情况下传递的,因此此代码输出数组的初始值(即 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);
}
4

2 回答 2

1

这是一个以图形方式解释发生了什么的尝试。您的 3 种方法(常规、CopyTo 和 ref)非常不同。

我已经概述了交换算法的相对复杂性,但大多数情况下你可以忽略它。关于这一切,最重要的一点是当你使用 时会发生什么ref,以及当你操纵正在传递的引用类型的内容时会发生什么。内容操作与将整个内容换成其他内容非常不同

点击展开..

在此处输入图像描述

于 2021-10-07T10:31:57.510 回答
-1

因为CopyTo()将元素设置在数组内部并且不会重新分配数组变量本身。

.ToArray()CopyTo()在修改它的同时创建一个新对象。后者获得了对现有数组的引用。

另请参阅按值和按引用传递数组以及许多其他内容。

于 2021-10-07T09:12:55.460 回答