0

I have a C# code as follows:

int[] A = new int[] {1, 2, 3};
fun(A);
// A at this point still says 1, 2, 3.

void fun(int[] A)
{
   int[] B = new int[] {4, 5, 6};
   A = B;
}

I thought all arrays are passed by reference in C#. Shouldn't A after calling fun() reflect 4, 5, 6?

Bugaboo
  • 973
  • 1
  • 17
  • 36
  • You have to modify the original reference to A, you never do. See [the docs](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-reference-type-parameters#passing-reference-types-by-value) – maccettura Jul 28 '17 at 20:32
  • 4
    The elements of the array are passed by reference, not the array itself. See: https://stackoverflow.com/questions/967402/are-arrays-or-lists-passed-by-default-by-reference-in-c – Archie Gertsman Jul 28 '17 at 20:33
  • When making examples you should not use the same name in multiple places, it makes it hard to talk about your example, the name of the parameter and the name of the variable passed in to the function should have been two different names to make the example easier to talk about. – Scott Chamberlain Jul 28 '17 at 20:37
  • @ArchieGertsman No, the elements aren't passed by reference. There is only one variable being passed, it's being passed *by value*, but that value *is a reference*. The array values are referenced, but they aren't "passed" at all by reference or otherwise. – Servy Jul 28 '17 at 20:39
  • @Servy My mistake. But that link still holds. – Archie Gertsman Jul 28 '17 at 20:43
  • @ArchieGertsman Indeed it does. – Servy Jul 28 '17 at 20:44

2 Answers2

2

I thought all arrays are passed by reference in C#

Actually (the reference of the original array object is passed by value) which is the usual behavior in case of reference types in C#.

Your understanding is partially correct, the reference is passed but is passed by value which means a new reference gets created which is pointing to the original array object A.

The fun(int[] A) has it's own copy of reference which is pointing to the array object which contains 1,2,3 and in the fun you create a new array object B and you are just assigning the reference of new one to your local method reference variable which of-course will not have any impact on the original A object which was passed as input to the fun.

You would need to pass it by reference if you want to reflect the changes made to A in fun to be reflected back to the original array object.

You can update the array items without passing by reference which is explained well in Scott Chamberlain's answer

Hope it Helps!

Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160
  • So you say that arrays are passed by reference, and then *later on in the same sentence*, say that they're passed by value. No, arrays *aren't* passed by reference, so don't say that they are. – Servy Jul 28 '17 at 20:41
  • the reference of the original array object is passed by value – Ehsan Sajjad Jul 28 '17 at 20:42
  • @Yes, that's correct, unlike the bolded statement in your answer saying that arrays are passed by reference, which is false. – Servy Jul 28 '17 at 20:43
  • i have updated my post to be more clear so that it doesn't confuses. – Ehsan Sajjad Jul 28 '17 at 20:45
2

The array is passed by a reference, you can see this by doing A[0] = 7; from inside another method.

That reference (held by the outer variable A), however is passed by value to the function. The reference is copied and a new variable is created and passed to the function. The variable outside the function is not affected by the reassignment to the parameter variable A inside the function.

To update the original variable you need to use the ref keyword so the parameter inside the function represents the same object as outside of the function.

int[] A = new int[] {1, 2, 3};
fun2(A);
// A at this point says 7, 2, 3.
fun(ref A);
// A at this point says 4, 5, 6.

void fun2(int[] a)
{
   a[0] = 7;
}

void fun(ref int[] a)
{
   int[] B = new int[] {4, 5, 6};
   a = B;
}
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • `The array is passed by reference` No, it's passed by value, as can be seen from the OP's code. If that statement were true, then the OP's code would have done what they expected it to do, not what it actually did. – Servy Jul 28 '17 at 20:39
  • @Servy did some rewording – Scott Chamberlain Jul 28 '17 at 20:50
  • Now the sentence just doesn't make sense. Did you mean to say the array passed *is* a reference, rather than *by* a reference? – Servy Jul 28 '17 at 20:54