The key to understanding this is to know the difference between a value type and a reference type.
For example, consider a typical value type, int
.
int a = 1;
int b = a;
a++;
After this code has executed, a
has the value 2, and b
has the value 1
. Because int
is a value type, b = a
takes a copy of the value of a
.
Now consider a class:
MyClass a = new MyClass();
a.MyProperty = 1;
MyClass b = a;
a.MyProperty = 2;
Because classes are reference types, b = a
merely assigns the reference rather than the value. So b
and a
both refer to the same object. Hence, after a.MyProperty = 2
executes, b.MyProperty == 2
since a
and b
refer to the same object.
Considering the code in your question, an array is a reference type and so for this function:
public static void FirstDouble(int[] array)
the variable array
is actually a reference, because int[]
is a reference type. So array
is a reference that is passed by value.
Thus, modifications made to array
inside the function are actually applied to the int[]
object to which array
refers. And so those modifications are visible to all references that refer to that same object. And that includes the reference that the caller holds.
Now, if we look at the implementation of this function:
public static void FirstDouble(int[] array)
{
//double each elements value
for (int i = 0; i < array.Length; i++)
array[i] *= 2;
//create new object and assign its reference to array
array = new int[] { 11, 12, 13 };
}
there is one further complication. The for
loop simply doubles each element of the int[]
that is passed to the function. That’s the modification that the caller sees. The second part is the assignment of a new int[]
object to the local variable array
. This is not visible to the caller because all it does is to change the target of the reference array
. And since the reference array
is passed by value, the caller does not see that new object.
If the function had been declared like this:
public static void FirstDouble(ref int[] array)
then the reference array
would have been passed by reference and the caller would see the newly created object { 11, 12, 13 }
when the function returned.