Why pass an array by reference to the Array.Resize() method?

The abstract Array class has a static method Array.Resize(ref T[] array, int newSize), which, as you can see, takes the first parameter by reference.

For example, consider this code:

static void Main()
{
    int[] intArray = { 1, 2, 3 };  

    Array.Resize(ref intArray, 2); 
}

1) Why pass intArray by reference, since all arrays are of the reference type anyway?

2) Perhaps this saves you from writing such a

static void Main()
{
    int[] intArray4;

    Array.Resize(ref intArray, 2);
}

Here an error occurs at the compilation stage, because ref requires intArray to be initialized the calling code. But you can initialize it with the value null:

static void Main()
{
    int[] intArray4 = null;  

    Array.Resize(ref intArray, 2); 
}

And I think the meaning is lost, or not?


QUESTION

What is the benefit of using ref with reference types?


UPDATE

After this post was published, a member of the community noted that it might be a duplicate and I was directed to the article Ref for reference types. The article brought me more up to date, but I didn't get an answer there found. It turns out that even for myself, the question was not clearly formulated. But after @velial's response and + additionally read article Passing parameters of the reference type I realized what I was confused about: I did not understand that Array.Resize() in its work creates a new array for which it allocates a separate memory in the heap and it creates a new reference to this memory or uses an existing one, that's where the "bastard is buried".

Author: Adam Shakhabov, 2018-01-26

1 answers

The bottom line is that any variable is a value.

A reference type variable is no exception - its value is a reference to some object (yes, an array is also an object).

Accordingly, by calling Array.Resize(ref intArray, 2), we mean that the value of the reference may change as a result of calling this method.

In other words, we give the function Array.Resize() one array as input, and we get a completely different array as output.

Try to run the following example, then remove the keyword ref from the declaration and function call ExtendArray(), and run again :)

using System;
using System.Linq;

class Solution
{
    static void ExtendArray<T>(ref T[] array, T new_value)
    {
        if (array != null)
        {
            Array.Resize(ref array, array.Length + 1);
            array[array.Length - 1] = new_value;
        }
        else
            array = new T[] { new_value };
    }

    static void Main(string[] args)
    {
        int[] data = new int[] { 0, 1, 2, 3 };

        Console.Write("До вызова ExtendArray: \n  {0}\n", string.Join(", ", data.Select(v => v.ToString())));
        ExtendArray(ref data, 4);
        Console.Write("После вызова ExtendArray: \n  {0}\n", string.Join(", ", data.Select(v => v.ToString())));
    }
}

If the keyword ref is present, we have the following output:

Before calling ExtendArray:

0, 1, 2, 3

After calling ExtendArray:

0, 1, 2, 3, 4

What follows from this-in the calling code (the Main function()) the variable data changed its value and started pointing to another array. Because passed by reference with the keyword ref.

In the absence of the keyword ref, we have the following output:

Before calling ExtendArray:

0, 1, 2, 3

After calling ExtendArray:

0, 1, 2, 3

What we have here-inside the function ExtendArray() a new array is created, then in the calling code the variable data continues to point to the old version of the array-yes, precisely because the reference to the array itself was passed to by value, not by reference.

Yes, if you have never coded in languages like C++ and Pascal, then the phrase "link to link" may not sound very nice.

But nevertheless, there is nothing "criminal" about it" :)

 3
Author: velial, 2020-06-12 12:52:24