Search code examples
c#arraysref

Why is an array passed without ref, changed by CopyTo inside the method?


As the array parameter is passed without ref-keyword, this code outputs initial value of array (i.e. 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();
    }
}

It is obvious, because inside the Rotate method there is it's own array with values, copied from the parameter values. And if I want to change arr values in the calling method, I need to pass it to the Rotate method by ref, it works. But I don't understand, why if replace assignment with CopyTo() method the parameter behaves as like it is passed by reference:

static void Rotate(int[] nums, int k)
{
    var tail = nums.TakeLast(k).ToArray();

    tail.Concat(nums)
        .Take(nums.Length)
        .ToArray()
        .CopyTo(nums, 0);
}

Solution

  • Here's a go at explaining what happens, graphically. Your 3 approaches (regular, CopyTo, and ref) are very different..

    I've sketched in the relative complexity of the swapping algo but mostly you can ignore it. The most important point about all this is around what happens when you use ref, and what happens when you manipulate the contents of a reference type that is being passed around. Contents manipulation is very different to swapping the whole thing out for something else

    Click to expand..

    enter image description here