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".
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" :)