-1

I'm trying to understand exactly what's happening in this code below:

static void someMethod(int[] a) {
    int[] b = new int[5];
    a = b;
}

static void Main(string[] args) {
    int[] arr = new int[10];
    someMethod(arr);
    Console.WriteLine(arr.Length);
}

The thing I can't explain is why the Console.Writeline() prints 10 and not 5. Arrays in C# are reference types, so I would've thought the line a = b sets the variable a to point to an array of int[5]. Yet the Console.Writeline() prints 10. I'm at a loss to explain this value-type-like behavior of arrays. Can someone explain this?

GSerg
  • 76,472
  • 17
  • 159
  • 346
scantrell
  • 111
  • 1
  • 6
  • 1
    Try add `ref` modifier and see difference. – Alexander Petrov Apr 17 '21 at 17:18
  • Good thought, just tried it...after adding ref, Console.Writeline() now prints 5. But I'd still like to be able to explain the behavior without ref. Why is a reference type behaving with value-type semantics ? What's the underlying principle involved ? – scantrell Apr 17 '21 at 17:24
  • 1
    Does this answer your question? [Reference type still needs pass by ref?](https://stackoverflow.com/questions/1381881/reference-type-still-needs-pass-by-ref) –  Apr 17 '21 at 17:36
  • Suppose instead your program was `void M(int a) { int b = 5; a = b; } ... int a = 10; M(a); WriteLine(a);` In that program do you expect it to write 5 or 10? Can you explain why? If you can explain why for this simpler program, well, you can explain why for your more complicated program too. If you cannot, then concentrate on understanding the simpler program first before you get arrays into it. – Eric Lippert Apr 17 '21 at 18:59
  • 1
    Another question you might ponder: how many local variables are there in your program? Do you believe that there are two local variables, and that both `int a` are the *same* variable? Do you believe that `a = b` makes `a` and `b` the *same* variable, or two variables with the same value? You might have some fundamental misunderstanding about variables here that explains your confusion, and it would be good to track down what it is. – Eric Lippert Apr 17 '21 at 19:07
  • A third question you might ponder is: why do you think that this is an example of "a reference type behaving with value type semantics"? If you had to fill in the blank of "the value of a variable of reference type is a _____" how would you fill in the blank? If it's not "reference", then what is it? If it is "reference", then you've answered your question: variables of reference type behave like they contain values and those values are references. – Eric Lippert Apr 17 '21 at 19:15

2 Answers2

5

Think of a, b, and arr like boxes you can store references in.

You store a reference in arr. You pass the reference, but not the box itself, to someMethod, which sticks that reference in its own box, a.

You then create a new object and store a reference to it in b. Then you take the reference that is inside b, and stick it inside a, replacing the reference to the passed-in array inside that box.

But this does not change the value stored in arr, which contains the originally referenced object.

You can modify the referenced object, however:

static void someMethod(int[] a) 
{
    a[2] = 10;
    a[3] = 7;
}

static void Main(string[] args) 
{
    int[] arr = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    someMethod(arr);
    Console.WriteLine(arr[2]);
}

You will find that the array has been modified.

Using the ref keyword, as suggested in the comments, basically tells it to pass the "box" itself. See the documentation for more information.

-3

The assignment is writing an int pointer, not copying the array definition or its items. After assigning that pointer, the size of the array does not change. Even though it is now pointing to just 5 ints.

Howlium
  • 1,218
  • 1
  • 8
  • 19